// // String+Helpers.swift // KeymanEngine // // Created by Gabriel Wong on 2017-10-12. // Copyright © 2017 SIL International. All rights reserved. // import Foundation extension String { var hasFontExtension: Bool { return hasExtension(FileExtensions.trueTypeFont) || hasSuffix(FileExtensions.openTypeFont) } var hasJavaScriptExtension: Bool { return hasExtension(FileExtensions.javaScript) } func hasExtension(_ ext: String) -> Bool { return lowercased().hasSuffix(".\(ext)") } /// - Parameter separator: The separator between code units. /// - Returns: This String interpreted as hex-encoded UTF-16 code units. func stringFromUTF16CodeUnits(separatedBy separator: String = ",") -> String? { // TODO: Use one scanner for the whole String instead of splitting by comma first let hexStrings = components(separatedBy: separator) var codeUnits: [UInt16] = [] for hexString in hexStrings { let scanner = Scanner(string: hexString) var codeUnit: UInt32 = 0 if scanner.scanHexInt32(&codeUnit) && scanner.isAtEnd { codeUnits.append(UInt16(codeUnit)) } else { return nil } } return String(utf16CodeUnits: codeUnits, count: codeUnits.count) } } func trimDirectionalMarkPrefix(_ str: String?) -> String { var text = str ?? "" let DIRECTIONAL_MARKS = [ UnicodeScalar("\u{200e}"), UnicodeScalar("\u{200f}"), UnicodeScalar("\u{202e}") ] // If the first intended char in context is a diacritic (such as U+0300), Swift's // standard string-handling will treat it and a preceding directional character // as a single unit. This code block exists to avoid the issue. if text.utf16.count > 0 { let head = UnicodeScalar(text.utf16[text.utf16.startIndex])! let tail = text.utf16.count > 1 ? String(text.utf16[text.utf16.index(text.utf16.startIndex, offsetBy: 1)..