Tekkon // v1.5.1 Update, removing Foundation dependency.
This commit is contained in:
parent
7ef7f33993
commit
86b8fa5f79
|
@ -6,8 +6,6 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// The namespace for this package.
|
||||
public enum Tekkon {
|
||||
// MARK: - Static Constants
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Tekkon {
|
||||
// MARK: - Dynamic Constants and Basic Enums
|
||||
|
||||
|
@ -115,7 +113,7 @@ public extension Tekkon {
|
|||
/// - strOf: 要取代的內容。
|
||||
/// - strWith: 要取代成的內容。
|
||||
public mutating func selfReplace(_ strOf: String, _ strWith: String = "") {
|
||||
valueStorage = valueStorage.replacingOccurrences(of: strOf, with: strWith)
|
||||
if valueStorage == strOf { valueStorage = strWith }
|
||||
ensureType()
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Tekkon {
|
||||
// MARK: - Syllable Composer
|
||||
|
||||
|
@ -65,7 +63,7 @@ public extension Tekkon {
|
|||
public func getComposition(isHanyuPinyin: Bool = false, isTextBookStyle: Bool = false) -> String {
|
||||
switch isHanyuPinyin {
|
||||
case false: // 注音輸出的場合
|
||||
let valReturnZhuyin = value.replacingOccurrences(of: " ", with: "")
|
||||
let valReturnZhuyin = value.swapping(" ", with: "")
|
||||
return isTextBookStyle ? cnvPhonaToTextbookReading(target: valReturnZhuyin) : valReturnZhuyin
|
||||
case true: // 拼音輸出的場合
|
||||
let valReturnPinyin = Tekkon.cnvPhonaToHanyuPinyin(targetJoined: value)
|
||||
|
@ -87,7 +85,7 @@ public extension Tekkon {
|
|||
case "˙": toneReturned = "5"
|
||||
default: break
|
||||
}
|
||||
return romajiBuffer.replacingOccurrences(of: "v", with: "ü") + toneReturned
|
||||
return romajiBuffer.swapping("v", with: "ü") + toneReturned
|
||||
}
|
||||
|
||||
/// 注拼槽內容是否為空。
|
||||
|
@ -132,39 +130,45 @@ public extension Tekkon {
|
|||
/// 注意:回傳結果會受到當前注音排列 parser 屬性的影響。
|
||||
/// - Parameters:
|
||||
/// - key: 傳入的 UniChar 內容。
|
||||
public func inputValidityCheck(key inputKey: UniChar = 0) -> Bool {
|
||||
if let scalar = UnicodeScalar(inputKey) {
|
||||
let input = String(scalar)
|
||||
switch parser {
|
||||
case .ofDachen:
|
||||
return Tekkon.mapQwertyDachen[input] != nil
|
||||
case .ofDachen26:
|
||||
return Tekkon.mapDachenCP26StaticKeys[input] != nil
|
||||
case .ofETen:
|
||||
return Tekkon.mapQwertyETenTraditional[input] != nil
|
||||
case .ofHsu:
|
||||
return Tekkon.mapHsuStaticKeys[input] != nil
|
||||
case .ofETen26:
|
||||
return Tekkon.mapETen26StaticKeys[input] != nil
|
||||
case .ofIBM:
|
||||
return Tekkon.mapQwertyIBM[input] != nil
|
||||
case .ofMiTAC:
|
||||
return Tekkon.mapQwertyMiTAC[input] != nil
|
||||
case .ofSeigyou:
|
||||
return Tekkon.mapSeigyou[input] != nil
|
||||
case .ofFakeSeigyou:
|
||||
return Tekkon.mapFakeSeigyou[input] != nil
|
||||
case .ofStarlight:
|
||||
return Tekkon.mapStarlightStaticKeys[input] != nil
|
||||
case .ofAlvinLiu:
|
||||
return Tekkon.mapAlvinLiuStaticKeys[input] != nil
|
||||
case .ofWadeGilesPinyin:
|
||||
return Tekkon.mapWadeGilesPinyinKeys.contains(input)
|
||||
case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin:
|
||||
return Tekkon.mapArayuruPinyin.contains(input)
|
||||
}
|
||||
public func inputValidityCheck(key inputKey: UInt16 = 0) -> Bool {
|
||||
guard let scalar = UnicodeScalar(inputKey) else { return false }
|
||||
return inputValidityCheck(charStr: String(scalar))
|
||||
}
|
||||
|
||||
/// 用於檢測「某個輸入字符訊號的合規性」的函式。
|
||||
///
|
||||
/// 注意:回傳結果會受到當前注音排列 parser 屬性的影響。
|
||||
/// - Parameters:
|
||||
/// - charStr: 傳入的字元(String)。
|
||||
public func inputValidityCheck(charStr input: String) -> Bool {
|
||||
switch parser {
|
||||
case .ofDachen:
|
||||
return Tekkon.mapQwertyDachen[input] != nil
|
||||
case .ofDachen26:
|
||||
return Tekkon.mapDachenCP26StaticKeys[input] != nil
|
||||
case .ofETen:
|
||||
return Tekkon.mapQwertyETenTraditional[input] != nil
|
||||
case .ofHsu:
|
||||
return Tekkon.mapHsuStaticKeys[input] != nil
|
||||
case .ofETen26:
|
||||
return Tekkon.mapETen26StaticKeys[input] != nil
|
||||
case .ofIBM:
|
||||
return Tekkon.mapQwertyIBM[input] != nil
|
||||
case .ofMiTAC:
|
||||
return Tekkon.mapQwertyMiTAC[input] != nil
|
||||
case .ofSeigyou:
|
||||
return Tekkon.mapSeigyou[input] != nil
|
||||
case .ofFakeSeigyou:
|
||||
return Tekkon.mapFakeSeigyou[input] != nil
|
||||
case .ofStarlight:
|
||||
return Tekkon.mapStarlightStaticKeys[input] != nil
|
||||
case .ofAlvinLiu:
|
||||
return Tekkon.mapAlvinLiuStaticKeys[input] != nil
|
||||
case .ofWadeGilesPinyin:
|
||||
return Tekkon.mapWadeGilesPinyinKeys.has(string: input)
|
||||
case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin:
|
||||
return Tekkon.mapArayuruPinyin.has(string: input)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/// 按需更新拼音組音區的內容顯示。
|
||||
|
@ -222,7 +226,7 @@ public extension Tekkon {
|
|||
/// 如果是諸如複合型注音排列的話,翻譯結果有可能為空,但翻譯過程已經處理好聲介韻調分配了。
|
||||
/// - Parameters:
|
||||
/// - fromCharCode: 傳入的 UniChar 內容。
|
||||
public mutating func receiveKey(fromCharCode inputCharCode: UniChar = 0) {
|
||||
public mutating func receiveKey(fromCharCode inputCharCode: UInt16 = 0) {
|
||||
if let scalar = UnicodeScalar(inputCharCode) {
|
||||
receiveKey(fromString: String(scalar))
|
||||
}
|
||||
|
@ -781,6 +785,6 @@ public extension Tekkon {
|
|||
|
||||
private extension String {
|
||||
func doesHave(_ target: String) -> Bool {
|
||||
target.isEmpty ? isEmpty : contains(target)
|
||||
has(string: target)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Tekkon {
|
||||
// MARK: - Phonabet to Hanyu-Pinyin Conversion Processing
|
||||
|
||||
|
@ -17,7 +15,7 @@ public extension Tekkon {
|
|||
static func cnvPhonaToHanyuPinyin(targetJoined: String) -> String {
|
||||
var targetConverted = targetJoined
|
||||
for pair in arrPhonaToHanyuPinyin {
|
||||
targetConverted = targetConverted.replacingOccurrences(of: pair[0], with: pair[1])
|
||||
targetConverted = targetConverted.swapping(pair[0], with: pair[1])
|
||||
}
|
||||
return targetConverted
|
||||
}
|
||||
|
@ -28,7 +26,7 @@ public extension Tekkon {
|
|||
static func cnvHanyuPinyinToTextbookStyle(targetJoined: String) -> String {
|
||||
var targetConverted = targetJoined
|
||||
for pair in arrHanyuPinyinTextbookStyleConversionTable {
|
||||
targetConverted = targetConverted.replacingOccurrences(of: pair[0], with: pair[1])
|
||||
targetConverted = targetConverted.swapping(pair[0], with: pair[1])
|
||||
}
|
||||
return targetConverted
|
||||
}
|
||||
|
@ -54,7 +52,7 @@ public extension Tekkon {
|
|||
target: String
|
||||
) -> String {
|
||||
var newNeta = target
|
||||
if !"ˊˇˋ˙".contains(String(target.reversed()[0])), !target.contains("_") { newNeta += "1" }
|
||||
if !"ˊˇˋ˙".has(string: String(target.reversed()[0])), !target.has(string: "_") { newNeta += "1" }
|
||||
return newNeta
|
||||
}
|
||||
|
||||
|
@ -69,11 +67,11 @@ public extension Tekkon {
|
|||
var result = targetJoined
|
||||
for key in Tekkon.mapHanyuPinyin.keys.sorted(by: { $0.count > $1.count }) {
|
||||
guard let value = Tekkon.mapHanyuPinyin[key] else { continue }
|
||||
result = result.replacingOccurrences(of: key, with: value)
|
||||
result = result.swapping(key, with: value)
|
||||
}
|
||||
for key in Tekkon.mapArayuruPinyinIntonation.keys.sorted(by: { $0.count > $1.count }) {
|
||||
guard let value = Tekkon.mapArayuruPinyinIntonation[key] else { continue }
|
||||
result = result.replacingOccurrences(of: key, with: (key == "1") ? newToneOne : value)
|
||||
result = result.swapping(key, with: (key == "1") ? newToneOne : value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -82,8 +80,82 @@ public extension Tekkon {
|
|||
/// 檢測字串是否包含半形英數內容
|
||||
private extension String {
|
||||
var isNotPureAlphanumerical: Bool {
|
||||
let regex = ".*[^A-Za-z0-9].*"
|
||||
let testString = NSPredicate(format: "SELF MATCHES %@", regex)
|
||||
return testString.evaluate(with: self)
|
||||
let x = unicodeScalars.map(\.value).filter {
|
||||
if $0 >= 48, $0 <= 57 { return false }
|
||||
if $0 >= 65, $0 <= 90 { return false }
|
||||
if $0 >= 97, $0 <= 122 { return false }
|
||||
return true
|
||||
}
|
||||
return !x.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
// This package is trying to deprecate its dependency of Foundation, hence the following contents.
|
||||
|
||||
extension StringProtocol {
|
||||
func has(string target: any StringProtocol) -> Bool {
|
||||
let selfArray = Array(unicodeScalars)
|
||||
let targetArray = Array(target.description.unicodeScalars)
|
||||
guard !target.isEmpty else { return isEmpty }
|
||||
guard count >= target.count else { return false }
|
||||
for index in 0 ..< selfArray.count {
|
||||
let range = index ..< (Swift.min(index + targetArray.count, selfArray.count))
|
||||
let ripped = Array(selfArray[range])
|
||||
if ripped == targetArray { return true }
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func sliced(by separator: any StringProtocol = "") -> [String] {
|
||||
let selfArray = Array(unicodeScalars)
|
||||
let arrSeparator = Array(separator.description.unicodeScalars)
|
||||
var result: [String] = []
|
||||
var buffer: [Unicode.Scalar] = []
|
||||
var sleepCount = 0
|
||||
for index in 0 ..< selfArray.count {
|
||||
let currentChar = selfArray[index]
|
||||
let range = index ..< (Swift.min(index + arrSeparator.count, selfArray.count))
|
||||
let ripped = Array(selfArray[range])
|
||||
if ripped.isEmpty { continue }
|
||||
if ripped == arrSeparator {
|
||||
sleepCount = range.count
|
||||
result.append(buffer.map { String($0) }.joined())
|
||||
buffer.removeAll()
|
||||
}
|
||||
if sleepCount < 1 {
|
||||
buffer.append(currentChar)
|
||||
}
|
||||
sleepCount -= 1
|
||||
}
|
||||
result.append(buffer.map { String($0) }.joined())
|
||||
buffer.removeAll()
|
||||
return result
|
||||
}
|
||||
|
||||
func swapping(_ target: String, with newString: String) -> String {
|
||||
let selfArray = Array(unicodeScalars)
|
||||
let arrTarget = Array(target.description.unicodeScalars)
|
||||
var result = ""
|
||||
var buffer: [Unicode.Scalar] = []
|
||||
var sleepCount = 0
|
||||
for index in 0 ..< selfArray.count {
|
||||
let currentChar = selfArray[index]
|
||||
let range = index ..< (Swift.min(index + arrTarget.count, selfArray.count))
|
||||
let ripped = Array(selfArray[range])
|
||||
if ripped.isEmpty { continue }
|
||||
if ripped == arrTarget {
|
||||
sleepCount = ripped.count
|
||||
result.append(buffer.map { String($0) }.joined())
|
||||
result.append(newString)
|
||||
buffer.removeAll()
|
||||
}
|
||||
if sleepCount < 1 {
|
||||
buffer.append(currentChar)
|
||||
}
|
||||
sleepCount -= 1
|
||||
}
|
||||
result.append(buffer.map { String($0) }.joined())
|
||||
buffer.removeAll()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue