@@ -23,10 +23,13 @@ public struct XMReverter {
2323
2424 public func run( ) throws {
2525 let xcstrings = try extractXCStrings ( )
26- let array = convertToStringsData ( from: xcstrings)
27- try array . forEach { stringsData in
26+ let ( stringsArray , stringsDictArray ) = convertToStringsData ( from: xcstrings)
27+ try stringsArray . forEach { stringsData in
2828 try exportStringsFile ( stringsData)
2929 }
30+ try stringsDictArray. forEach { stringsData in
31+ try exportStringsDictFile ( stringsData)
32+ }
3033 standardOutput ( " Completed. " )
3134 }
3235
@@ -44,20 +47,42 @@ public struct XMReverter {
4447 }
4548 }
4649
47- func convertToStringsData( from xcstrings: XCStrings ) -> [ StringsData ] {
48- xcstrings. strings. reduce ( into: [ StringsData] ( ) ) { partialResult, item in
49- item. value. localizations. forEach { language, localization in
50- if let index = partialResult. firstIndex ( where: { $0. language == language } ) {
51- partialResult [ index] . values [ item. key] = localization. stringUnit. value
52- } else {
53- partialResult. append ( StringsData (
54- tableName: " Localizable " ,
55- language: language,
56- values: [ item. key : localization. stringUnit. value]
57- ) )
50+ func convertToStringsData( from xcstrings: XCStrings ) -> ( strings: [ StringsData ] , stringsdict: [ StringsData ] ) {
51+ var stringsArray : [ StringsData ] = [ ]
52+ var stringsDictArray : [ StringsData ] = [ ]
53+
54+ xcstrings. strings. forEach { stringKey, strings in
55+ strings. localizations. forEach { language, localization in
56+ // Check if this is a plural variation or simple string
57+ if let variations = localization. variations,
58+ let pluralVariations = variations. plural {
59+ // Handle plural - goes to stringsdict
60+ let pluralValues = pluralVariations. mapValues { $0. stringUnit. value }
61+ if let index = stringsDictArray. firstIndex ( where: { $0. language == language } ) {
62+ stringsDictArray [ index] . values [ stringKey] = . plural( pluralValues)
63+ } else {
64+ stringsDictArray. append ( StringsData (
65+ tableName: " Localizable " ,
66+ language: language,
67+ values: [ stringKey: . plural( pluralValues) ]
68+ ) )
69+ }
70+ } else if let stringUnit = localization. stringUnit {
71+ // Handle simple string - goes to strings
72+ if let index = stringsArray. firstIndex ( where: { $0. language == language } ) {
73+ stringsArray [ index] . values [ stringKey] = . simple( stringUnit. value)
74+ } else {
75+ stringsArray. append ( StringsData (
76+ tableName: " Localizable " ,
77+ language: language,
78+ values: [ stringKey: . simple( stringUnit. value) ]
79+ ) )
80+ }
5881 }
5982 }
6083 }
84+
85+ return ( stringsArray, stringsDictArray)
6186 }
6287
6388 func exportStringsFile( _ stringsData: StringsData ) throws {
@@ -71,12 +96,66 @@ public struct XMReverter {
7196 . appendingPathExtension ( " strings " )
7297 let text = stringsData. values
7398 . sorted ( by: { $0. key < $1. key } )
74- . map { " \( $0. key. debugDescription) = \( $0. value. debugDescription) ; " }
99+ . compactMap { key, value -> String ? in
100+ guard case . simple( let stringValue) = value else { return nil }
101+ return " \( key. debugDescription) = \( stringValue. debugDescription) ; "
102+ }
75103 . joined ( separator: " \n " )
76104 try writeString ( text, outputFileURL)
77105 standardOutput ( " Succeeded to export strings file. " )
78106 } catch {
79107 throw XMError . failedToExportStringsFile
80108 }
81109 }
110+
111+ func exportStringsDictFile( _ stringsData: StringsData ) throws {
112+ do {
113+ let outputFolderURL = URL ( filePath: outputPath)
114+ . appending ( path: stringsData. language)
115+ . appendingPathExtension ( " lproj " )
116+ try createDirectory ( outputFolderURL)
117+ let outputFileURL = outputFolderURL
118+ . appending ( path: stringsData. tableName)
119+ . appendingPathExtension ( " stringsdict " )
120+
121+ // Build the plist dictionary
122+ var plistDict : [ String : [ String : Any ] ] = [ : ]
123+
124+ for (key, value) in stringsData. values. sorted ( by: { $0. key < $1. key } ) {
125+ guard case . plural( let pluralRules) = value else { continue }
126+
127+ // Create the variable name (use "format" as default)
128+ let variableName = " format "
129+
130+ // Build the variable dictionary
131+ var variableDict : [ String : Any ] = [
132+ " NSStringFormatSpecTypeKey " : " NSStringPluralRuleType " ,
133+ " NSStringFormatValueTypeKey " : " li "
134+ ]
135+
136+ // Add plural rules
137+ for (pluralKey, pluralValue) in pluralRules {
138+ variableDict [ pluralKey] = pluralValue
139+ }
140+
141+ // Build the top-level dictionary for this key
142+ plistDict [ key] = [
143+ " NSStringLocalizedFormatKey " : " %#@ \( variableName) @ " ,
144+ variableName: variableDict
145+ ]
146+ }
147+
148+ // Convert to XML plist
149+ let plistData = try PropertyListSerialization . data (
150+ fromPropertyList: plistDict,
151+ format: . xml,
152+ options: 0
153+ )
154+
155+ try plistData. write ( to: outputFileURL)
156+ standardOutput ( " Succeeded to export stringsdict file. " )
157+ } catch {
158+ throw XMError . failedToExportStringsFile
159+ }
160+ }
82161}
0 commit comments