// // StringsFileGenerator.swift // // // Created by Thibaut Schmitt on 04/01/2022. // import Foundation import ToolCore class StringsFileGenerator { // MARK: - Strings Files static func writeStringsFiles(sections: [Section], langs: [String], defaultLang: String, tags: [String], outputPath: String, inputFilenameWithoutExt: String) { var stringsFilesContent = [String: String]() for lang in langs { stringsFilesContent[lang] = Self.generateStringsFileContent(lang: lang, defaultLang: defaultLang, tags: tags, sections: sections) } // Write strings file content langs.forEach { lang in guard let fileContent = stringsFilesContent[lang] else { return } let stringsFilePath = "\(outputPath)/\(lang).lproj/\(inputFilenameWithoutExt).strings" let stringsFilePathURL = URL(fileURLWithPath: stringsFilePath) do { try fileContent.write(to: stringsFilePathURL, atomically: false, encoding: .utf8) } catch (let error) { let error = StringiumError.writeFile(error.localizedDescription, stringsFilePath) print(error.description) Stringium.exit(withError: error) } } } static func generateStringsFileContent(lang: String, defaultLang: String, tags inputTags: [String], sections: [Section]) -> String { var stringsFileContent = """ /** * Apple Strings File * Generated by ResgenSwift \(ResgenSwiftVersion) * Language: \(lang) */\n """ sections.forEach { section in // Check that at least one string will be generated guard section.hasOneOrMoreMatchingTags(tags: inputTags) else { return // Go to next section } stringsFileContent += "\n/********** \(section.name) **********/\n\n" section.definitions.forEach { definition in var skipDefinition = false // Set to true if not matching tag let translationOpt: String? = { // If no matching tag => skip if definition.hasOneOrMoreMatchingTags(inputTags: inputTags) == false { skipDefinition = true return nil } // If tags contains `noTranslationTag` => get default lang if definition.tags.contains(Stringium.noTranslationTag) { return definition.translations[defaultLang] } // Else: get specific lang return definition.translations[lang] }() if let translation = translationOpt { stringsFileContent += "\"\(definition.name)\" = \"\(translation)\";\n\n" } else if skipDefinition == false { let error = StringiumError.langNotDefined(lang, definition.name, definition.reference != nil) print(error.description) Stringium.exit(withError: error) } } } return stringsFileContent } // MARK: - Extension file static func writeExtensionFiles(sections: [Section], defaultLang lang: String, tags: [String], staticVar: Bool, inputFilename: String, extensionName: String, extensionFilePath: String, extensionSuffix: String) { // Get extension content let extensionFileContent = Self.getExtensionContent(sections: sections, defaultLang: lang, tags: tags, staticVar: staticVar, inputFilename: inputFilename, extensionName: extensionName, extensionSuffix: extensionSuffix) // Write content let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath) do { try extensionFileContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8) } catch (let error) { let error = StringiumError.writeFile(extensionFilePath, error.localizedDescription) print(error.description) Stringium.exit(withError: error) } } // MARK: - Extension content static func getExtensionContent(sections: [Section], defaultLang lang: String, tags: [String], staticVar: Bool, inputFilename: String, extensionName: String, extensionSuffix: String) -> String { [ Self.getHeader(stringsFilename: inputFilename, extensionClassname: extensionName), Self.getEnumKey(sections: sections, tags: tags, extensionSuffix: extensionSuffix), Self.getProperties(sections: sections, defaultLang: lang, tags: tags, staticVar: staticVar), Self.getFooter() ] .joined(separator: "\n") } // MARK: - Extension part private static func getHeader(stringsFilename: String, extensionClassname: String) -> String { """ // Generated by ResgenSwift.Strings.\(Stringium.toolName) \(ResgenSwiftVersion) import UIKit fileprivate let kStringsFileName = "\(stringsFilename)" extension \(extensionClassname) { """ } private static func getEnumKey(sections: [Section], tags: [String], extensionSuffix: String) -> String { var enumDefinition = "\n enum Key\(extensionSuffix.uppercasedFirst()): String {\n" sections.forEach { section in // Check that at least one string will be generated guard section.hasOneOrMoreMatchingTags(tags: tags) else { return // Go to next section } section.definitions.forEach { definition in guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { return // Go to next definition } debugPrint("Found definition") enumDefinition += " case \(definition.name) = \"\(definition.name)\"\n" } } enumDefinition += " }" return enumDefinition } private static func getProperties(sections: [Section], defaultLang lang: String, tags: [String], staticVar: Bool) -> String { sections.compactMap { section in // Check that at least one string will be generated guard section.hasOneOrMoreMatchingTags(tags: tags) else { return nil // Go to next section } var res = "\n // MARK: - \(section.name)\n" res += section.definitions.compactMap { definition in guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { return nil // Go to next definition } if staticVar { return "\n\(definition.getNSLocalizedStringStaticProperty(forLang: lang))" } return "\n\(definition.getNSLocalizedStringProperty(forLang: lang))" } .joined(separator: "\n") return res } .joined(separator: "\n") } private static func getFooter() -> String { """ } """ } }