diff --git a/HiperStrings/Controllers/ZFFileDetailController.m b/HiperStrings/Controllers/ZFFileDetailController.m index 15317cc..6eb6cd8 100644 --- a/HiperStrings/Controllers/ZFFileDetailController.m +++ b/HiperStrings/Controllers/ZFFileDetailController.m @@ -68,7 +68,7 @@ - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColum else { NSArray *translation = [self.langFile translationsByType:(self.segmentedControl.selectedSegment == 0)? ZFLangTypeIOS : ZFLangTypeAndorid andLanguageIdentifier:tableColumn.identifier]; ZFLangFile *lang = [translation lastObject]; - return [lang.translations objectForKey:[self.keys objectAtIndex:row]]; + return [[lang lineForKey:[self.keys objectAtIndex:row]] value]; } //return [[self.rows objectForKey:tableColumn.identifier] objectForKey:[self.keys objectAtIndex:row]]; diff --git a/Strings.xcodeproj/project.pbxproj b/Strings.xcodeproj/project.pbxproj index edd3e50..2a0bda9 100644 --- a/Strings.xcodeproj/project.pbxproj +++ b/Strings.xcodeproj/project.pbxproj @@ -44,6 +44,8 @@ 1371BBD8177D8E63008EB467 /* ZFExportFilesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1371BBD7177D8E63008EB467 /* ZFExportFilesController.m */; }; 1371BBDB177D90DD008EB467 /* ZFFileExportCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1371BBDA177D90DD008EB467 /* ZFFileExportCell.m */; }; 1371BBDE177DBDD9008EB467 /* ZFLangFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 1371BBDD177DBDD9008EB467 /* ZFLangFile.m */; }; + 137CBEA6177F2556003C472E /* ZFTranslationLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 137CBEA5177F2556003C472E /* ZFTranslationLine.m */; }; + 137CBEA7177F2B7F003C472E /* ZFTranslationLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 137CBEA5177F2556003C472E /* ZFTranslationLine.m */; }; 13B17AED177AFB6000C0473E /* ZFTranslationFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B17AEC177AFB6000C0473E /* ZFTranslationFile.m */; }; 13B17AEE177AFE2800C0473E /* ZFTranslationFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B17AEC177AFB6000C0473E /* ZFTranslationFile.m */; }; 13B17AEF177AFE2800C0473E /* ZFTranslationFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B17AEC177AFB6000C0473E /* ZFTranslationFile.m */; }; @@ -122,6 +124,8 @@ 1371BBDA177D90DD008EB467 /* ZFFileExportCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZFFileExportCell.m; path = Views/ZFFileExportCell.m; sourceTree = ""; }; 1371BBDC177DBDD9008EB467 /* ZFLangFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZFLangFile.h; sourceTree = ""; }; 1371BBDD177DBDD9008EB467 /* ZFLangFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZFLangFile.m; sourceTree = ""; }; + 137CBEA4177F2556003C472E /* ZFTranslationLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZFTranslationLine.h; sourceTree = ""; }; + 137CBEA5177F2556003C472E /* ZFTranslationLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZFTranslationLine.m; sourceTree = ""; }; 13B17AEB177AFB6000C0473E /* ZFTranslationFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZFTranslationFile.h; sourceTree = ""; }; 13B17AEC177AFB6000C0473E /* ZFTranslationFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZFTranslationFile.m; sourceTree = ""; }; 13B17AF0177B02F700C0473E /* ZFUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZFUtils.h; sourceTree = ""; }; @@ -236,6 +240,8 @@ 13B17AF1177B02F700C0473E /* ZFUtils.m */, 1371BBDC177DBDD9008EB467 /* ZFLangFile.h */, 1371BBDD177DBDD9008EB467 /* ZFLangFile.m */, + 137CBEA4177F2556003C472E /* ZFTranslationLine.h */, + 137CBEA5177F2556003C472E /* ZFTranslationLine.m */, ); name = Models; sourceTree = ""; @@ -469,6 +475,7 @@ 13B17AED177AFB6000C0473E /* ZFTranslationFile.m in Sources */, 13B17AF2177B02F700C0473E /* ZFUtils.m in Sources */, 1371BBDE177DBDD9008EB467 /* ZFLangFile.m in Sources */, + 137CBEA6177F2556003C472E /* ZFTranslationLine.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -489,6 +496,7 @@ 1371BBD8177D8E63008EB467 /* ZFExportFilesController.m in Sources */, 1371BBDB177D90DD008EB467 /* ZFFileExportCell.m in Sources */, 1323015F177DD7DD008EB3D5 /* ZFLangFile.m in Sources */, + 137CBEA7177F2B7F003C472E /* ZFTranslationLine.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Strings/ZFLangFile.h b/Strings/ZFLangFile.h index 759d1e7..8a59c40 100644 --- a/Strings/ZFLangFile.h +++ b/Strings/ZFLangFile.h @@ -7,6 +7,7 @@ // #import +#import "ZFTranslationLine.h" typedef enum { ZFLangTypeIOS, @@ -19,8 +20,10 @@ typedef enum { @property (nonatomic, strong, readonly) NSString *fileName; @property (nonatomic, assign, readonly) ZFLangType type; @property (nonatomic, strong, readonly) NSString *language; -@property (nonatomic, strong, readonly) NSMutableDictionary *translations; +@property (nonatomic, strong, readonly) NSArray *allKeys; +@property (nonatomic, strong, readonly) NSMutableArray *translations; - (id)initWithURL:(NSURL *)url; +- (ZFTranslationLine *)lineForKey:(NSString *)key; @end diff --git a/Strings/ZFLangFile.m b/Strings/ZFLangFile.m index 0fab945..d4bcba9 100644 --- a/Strings/ZFLangFile.m +++ b/Strings/ZFLangFile.m @@ -9,8 +9,16 @@ #import "ZFLangFile.h" #import "ZFStringsConverter.h" +@interface ZFLangFile () + +@property (nonatomic, strong) NSArray *keysAndComments; + +@end + @implementation ZFLangFile +@synthesize allKeys = _allKeys; + /*! @abstract @@ -37,12 +45,36 @@ - (id)initWithURL:(NSURL *)url { _language = lang; ZFStringsConverter *converter = [[ZFStringsConverter alloc] init]; - NSDictionary *translations = (isIOS)? [converter translationsForStringsAtURL:url] : [converter translationsForXMLAtURL:url]; + NSArray *translations = (isIOS)? [converter translationsForStringsAtURL:url] : [converter translationsForXMLAtURL:url]; - _translations = [NSMutableDictionary dictionaryWithDictionary:translations]; + _translations = [NSMutableArray arrayWithArray:translations]; } return self; } +#pragma mark - keys + +- (void)extractKeys { + self.keysAndComments = [self.translations valueForKey:@"key"]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (self BEGINSWITH %@)", @"*"]; + _allKeys = [self.keysAndComments filteredArrayUsingPredicate:predicate]; +} + +- (NSArray *)keysAndComments { + if (!_keysAndComments) [self extractKeys]; + return _keysAndComments; +} + +- (NSArray *)allKeys { + if (!_allKeys) [self extractKeys]; + return _allKeys; +} + +- (ZFTranslationLine *)lineForKey:(NSString *)key { + NSUInteger index = [self.keysAndComments indexOfObject:key]; + if (index == NSNotFound) return nil; + return [self.translations objectAtIndex:index]; +} + @end diff --git a/Strings/ZFStringsConverter.h b/Strings/ZFStringsConverter.h index ead3275..486e3cb 100644 --- a/Strings/ZFStringsConverter.h +++ b/Strings/ZFStringsConverter.h @@ -12,15 +12,11 @@ @interface ZFStringsConverter : NSObject -- (void)convertStringsAtURL:(NSURL *)stringsURL toXMLAtURL:(NSURL *)XMLURL __deprecated; -- (void)convertXMLAtURL:(NSURL *)XMLURL toStringsAtURL:(NSURL *)stringsURL __deprecated; +- (NSArray *)translationsForXMLAtURL:(NSURL *)XMLURL; +- (NSString *)xmlStringFromTranslations:(NSArray *)translations; - -- (NSDictionary *)translationsForXMLAtURL:(NSURL *)XMLURL; -- (NSString *)xmlStringFromDictionary:(NSDictionary *)dictionary; - -- (NSString *)stringsStringFromDictionary:(NSDictionary *)dictionary; -- (NSDictionary *)translationsForStringsAtURL:(NSURL *)stringsURL; +- (NSString *)stringsStringFromTranslations:(NSArray *)translations; +- (NSArray *)translationsForStringsAtURL:(NSURL *)stringsURL; - (NSString *)convertFormatForString:(NSString *)input isIOS:(BOOL)isIOS; diff --git a/Strings/ZFStringsConverter.m b/Strings/ZFStringsConverter.m index 5578b55..c9b33b5 100644 --- a/Strings/ZFStringsConverter.m +++ b/Strings/ZFStringsConverter.m @@ -10,6 +10,7 @@ #import "ZFStringsConverter.h" #import "Config.h" +#import "ZFTranslationLine.h" @implementation ZFStringsConverter @@ -61,17 +62,17 @@ - (NSString *)convertFormatForString:(NSString *)input isIOS:(BOOL)isIOS { @param stringsURL the url of the file to be converted - @return NSDictionary with the translations + @return NSArray with the translations @discussion The comments are not recorded so they are lost in this fase already. The same is true for the key sorting which is likely to become alphabetical in the process */ -- (NSDictionary *)translationsForStringsAtURL:(NSURL *)stringsURL { +- (NSArray *)translationsForStringsAtURL:(NSURL *)stringsURL { if (!stringsURL) return nil; - NSMutableDictionary *translation = [NSMutableDictionary dictionary]; + NSMutableArray *translation = [NSMutableArray array]; NSStringEncoding encoding; NSError *error; @@ -87,29 +88,35 @@ - (NSDictionary *)translationsForStringsAtURL:(NSURL *)stringsURL { NSString *key = [stringsString substringWithRange:[match rangeAtIndex:1]]; NSString *value = [stringsString substringWithRange:[match rangeAtIndex:2]]; - [translation setObject:value forKey:key]; + ZFTranslationLine *line = [ZFTranslationLine line]; + [line setKey:key]; + [line setValue:value]; + [line setPosition:idx]; + + [translation addObject:line]; }]; - return (NSDictionary *)translation; + return (NSArray *)translation; } /*! @abstract - Parse the dictionary of translations to a string ready to be written to a .strings file + Parse the translations to a string ready to be written to a .strings file - @param dictionary of translations + @param array of translations @return NSString ready in .strings format */ -- (NSString *)stringsStringFromDictionary:(NSDictionary *)dictionary { +- (NSString *)stringsStringFromTranslations:(NSArray *)translations { NSMutableString *stringsString = [NSMutableString string]; - [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { - [stringsString appendFormat:@"\"%@\" = \"%@\";\n", key, [self convertFormatForString:obj isIOS:YES]]; + [translations enumerateObjectsUsingBlock:^(ZFTranslationLine *line, NSUInteger idx, BOOL *stop) { + NSString *value = (line.type == ZFTranslationLineTypeFormattedString)? [self convertFormatForString:line.value isIOS:YES] : line.value; + [stringsString appendFormat:@"\"%@\" = \"%@\";\n", line.key, value]; }]; return (NSString *)stringsString; @@ -126,12 +133,15 @@ - (NSString *)stringsStringFromDictionary:(NSDictionary *)dictionary { @param MLXURL of the file to be converted - @return NSDictionary with the translations + @return NSArray with the translations */ -- (NSDictionary *)translationsForXMLAtURL:(NSURL *)XMLURL { - NSMutableDictionary *translation = [NSMutableDictionary dictionary]; +- (NSArray *)translationsForXMLAtURL:(NSURL *)XMLURL { + if (!XMLURL) return nil; + + NSMutableArray *translation = [NSMutableArray array]; + NSError *error = nil; NSXMLDocument *xml = [[NSXMLDocument alloc] initWithContentsOfURL:XMLURL options:NSDataReadingMappedIfSafe error:&error]; NSArray *nodes = [xml nodesForXPath:@"//resources/string" error:&error]; @@ -141,17 +151,22 @@ - (NSDictionary *)translationsForXMLAtURL:(NSURL *)XMLURL { NSString *key = [element attributeForName:@"name"].stringValue; NSString *value = [obj.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]]; - [translation setObject:value forKey:key]; + ZFTranslationLine *line = [ZFTranslationLine line]; + [line setKey:key]; + [line setValue:value]; + [line setPosition:idx]; + + [translation addObject:line]; }]; - return (NSDictionary *)translation; + return (NSArray *)translation; } /*! @abstract Parse the dictionary of transaltions to a string ready to be written on an .xml file - @param dictionary with the transaltions + @param array with the transaltions @return NSString ready to be written to an .xml file @@ -159,13 +174,15 @@ - (NSDictionary *)translationsForXMLAtURL:(NSURL *)XMLURL { */ -- (NSString *)xmlStringFromDictionary:(NSDictionary *)dictionary { +- (NSString *)xmlStringFromTranslations:(NSArray *)translations { NSMutableArray *elements = [NSMutableArray array]; - [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { + [translations enumerateObjectsUsingBlock:^(ZFTranslationLine *line, NSUInteger idx, BOOL *stop) { + NSXMLElement *element = [NSXMLElement elementWithName:@"string"]; - [element setAttributesAsDictionary:@{@"name" : key}]; - [element setStringValue:[self convertFormatForString:obj isIOS:NO]]; + [element setAttributesAsDictionary:@{@"name" : line.key}]; + NSString *value = (line.type == ZFTranslationLineTypeFormattedString)? [self convertFormatForString:line.value isIOS:NO] : line.value; + [element setStringValue:value]; [elements addObject:element]; }]; @@ -180,23 +197,4 @@ - (NSString *)xmlStringFromDictionary:(NSDictionary *)dictionary { return [xml XMLStringWithOptions:NSXMLNodePrettyPrint]; } -#pragma mark - Converters - -- (void)convertStringsAtURL:(NSURL *)stringsURL toXMLAtURL:(NSURL *)XMLURL __deprecated{ - NSDictionary *translations = [self translationsForStringsAtURL:stringsURL]; - NSString *translationsString = [self xmlStringFromDictionary:translations]; - - NSError *error; - [translationsString writeToURL:XMLURL atomically:YES encoding:NSUTF8StringEncoding error:&error]; -} - - -- (void)convertXMLAtURL:(NSURL *)XMLURL toStringsAtURL:(NSURL *)stringsURL __deprecated{ - NSDictionary *translations = [self translationsForXMLAtURL:XMLURL]; - NSString *translationsString = [self stringsStringFromDictionary:translations]; - - NSError *error; - [translationsString writeToURL:stringsURL atomically:YES encoding:NSUTF8StringEncoding error:&error]; -} - @end diff --git a/Strings/ZFTranslationFile.m b/Strings/ZFTranslationFile.m index 647ab57..7143b7c 100644 --- a/Strings/ZFTranslationFile.m +++ b/Strings/ZFTranslationFile.m @@ -51,9 +51,9 @@ - (NSArray *)hashKeys { _hashKeys = [self allKeys]; if (!_hashKeys || _hashKeys.count < KEY_COMAPARISON) { - + [self.translations enumerateObjectsUsingBlock:^(ZFLangFile *obj, NSUInteger idx, BOOL *stop) { - _hashKeys = obj.translations.allKeys; + _hashKeys = [obj.translations valueForKey:@"key"]; *stop = (_hashKeys.count >= KEY_COMAPARISON); }]; @@ -177,7 +177,7 @@ - (void)fillGaps { [self.translations enumerateObjectsUsingBlock:^(ZFLangFile *lang, NSUInteger idx, BOOL *stop) { if (![allLanguages containsObject:lang.language]) [allLanguages addObject:lang.language]; - [lang.translations.allKeys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) { + [[lang allKeys] enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) { if ([allKeys containsObject:key]) return; [allKeys addObject:key]; }]; @@ -280,11 +280,11 @@ - (BOOL)writeAllTranslations { NSError *error = nil; if (self.conversionDriver == ZFTranslationFileConversionDriverIOS) { - NSString *textOutput = [converter xmlStringFromDictionary:objIOS.translations]; + NSString *textOutput = [converter xmlStringFromTranslations:objIOS.translations]; [textOutput writeToURL:objAndorid.url atomically:YES encoding:NSUTF8StringEncoding error:&error]; } else { - NSString *textOutput = [converter stringsStringFromDictionary:objAndorid.translations]; + NSString *textOutput = [converter stringsStringFromTranslations:objAndorid.translations]; [textOutput writeToURL:objIOS.url atomically:YES encoding:NSUTF8StringEncoding error:&error]; } diff --git a/Strings/ZFTranslationLine.h b/Strings/ZFTranslationLine.h new file mode 100644 index 0000000..d2433d6 --- /dev/null +++ b/Strings/ZFTranslationLine.h @@ -0,0 +1,26 @@ +// +// ZFTranslationLine.h +// Strings +// +// Created by Francesco on 29/06/2013. +// Copyright (c) 2013 ziofritz. All rights reserved. +// + +#import + +typedef enum { + ZFTranslationLineTypeString, + ZFTranslationLineTypeFormattedString, + ZFTranslationLineTypeComment +}ZFTranslationLineType; + +@interface ZFTranslationLine : NSObject + +@property (nonatomic, strong) NSString *key; +@property (nonatomic, strong) NSString *value; +@property (nonatomic, assign) ZFTranslationLineType type; +@property (nonatomic, assign) NSUInteger position; + ++(ZFTranslationLine *)line; + +@end diff --git a/Strings/ZFTranslationLine.m b/Strings/ZFTranslationLine.m new file mode 100644 index 0000000..c50bd6a --- /dev/null +++ b/Strings/ZFTranslationLine.m @@ -0,0 +1,23 @@ +// +// ZFTranslationLine.m +// Strings +// +// Created by Francesco on 29/06/2013. +// Copyright (c) 2013 ziofritz. All rights reserved. +// + +#import "ZFTranslationLine.h" + +@implementation ZFTranslationLine + ++(ZFTranslationLine *)line { + ZFTranslationLine *line = [[ZFTranslationLine alloc] init]; + return line; +} + +- (void)setValue:(NSString *)value { + _value = value; + self.type = ([_value rangeOfString:@"%"].location == NSNotFound)? ZFTranslationLineTypeString : ZFTranslationLineTypeFormattedString; +} + +@end diff --git a/StringsTests/ZFStringConverterTests.m b/StringsTests/ZFStringConverterTests.m index 7abc966..00eb5af 100644 --- a/StringsTests/ZFStringConverterTests.m +++ b/StringsTests/ZFStringConverterTests.m @@ -64,7 +64,7 @@ - (void)testCopareConversions { NSDictionary *xmlTranslations = [self.converter translationsForXMLAtURL:xmlURL]; - NSMutableArray *allKeys = [NSMutableArray arrayWithArray:stringsTranslations.allKeys]; + NSMutableArray *allKeys = [NSMutableArray arrayWithArray:[stringsTranslation allKeys]]; [xmlTranslations enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) { [allKeys removeObject:key];