// // TwineFileParser.swift // // // Created by Thibaut Schmitt on 10/01/2022. // import Foundation class TwineFileParser { static func parse(_ inputFile: String) -> [Section] { let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8) let stringsByLines = inputFileContent.components(separatedBy: .newlines) var sections = [Section]() // Parse file stringsByLines.forEach { // Section if let section = Section.match($0) { sections.append(section) return } // Definition if let definition = Definition.match($0) { sections.last?.definitions.append(definition) return } // Definition content if $0.isEmpty == false { // fr = Test => ["fr ", " Test"] let splitLine = $0 .removeLeadingTrailingWhitespace() .split(separator: "=") guard let lastDefinition = sections.last?.definitions.last, let leftElement = splitLine.first else { return } let rightElement: String = splitLine.dropFirst().joined(separator: "=") // "fr " => "fr" let leftHand = String(leftElement).removeTrailingWhitespace() // " Test" => "Test" let rightHand = String(rightElement).removeLeadingWhitespace() // Handle comments, tags and translation switch leftHand { case "comments": lastDefinition.comment = rightHand case "tags": lastDefinition.tags = rightHand .split(separator: ",") .map { String($0) } case "ref": lastDefinition.reference = rightHand default: lastDefinition.translations[leftHand] = rightHand.escapeDoubleQuote() // Is a plurals strings (fr:one = Test) // Will be handle later //if leftHand.split(separator: ":").count > 1 { // lastDefinition.isPlurals = true //} } } } // Keep only valid definition var invalidDefinitionNames = [String]() sections.forEach { section in section.definitions = section.definitions .filter { if $0.isValid == false { invalidDefinitionNames.append($0.name) return false } return true } } if invalidDefinitionNames.count > 0 { print(" warning:[\(Stringium.toolName)] Found \(invalidDefinitionNames.count) definition (\(invalidDefinitionNames.joined(separator: ", "))") } return sections } }