Files
AzooKeyKanaKanjiConverter/Sources/SwiftUtils/CharacterUtils.swift
2025-06-15 19:34:25 +09:00

315 lines
10 KiB
Swift

//
// extension Character.swift
// Keyboard
//
// Created by ensan on 2020/09/03.
// Copyright © 2020 ensan. All rights reserved.
//
import Foundation
public enum CharacterUtils {
///
private static let kogakiKana: Set<Character> = [
"", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", ""
]
///
private static let dakutenKana: Set<Character> = [
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
]
///
static func isKogana(_ character: Character) -> Bool {
kogakiKana.contains(character)
}
/// (a-z, A-Z)
@inlinable public static func isRomanLetter(_ character: Character) -> Bool {
character.isASCII && character.isCased
}
///
public static func kogaki(_ character: Character) -> Character {
switch character {
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
default: return character
}
}
///
public static func ogaki(_ character: Character) -> Character {
switch character {
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
case "": return ""
default: return character
}
}
///
public static func isDakuten(_ character: Character) -> Bool {
dakutenKana.contains(character)
}
///
public static func dakuten(_ character: Character) -> Character {
switch character {
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
default: return character
}
}
///
public static func mudakuten(_ character: Character) -> Character {
switch character {
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
default: return character
}
}
///
public static func isHandakuten(_ character: Character) -> Bool {
[
"", "", "", "", "",
"", "", "", "", ""
].contains(character)
}
///
public static func handakuten(_ character: Character) -> Character {
switch character {
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
default: return character
}
}
///
public static func muhandakuten(_ character: Character) -> Character {
switch character {
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
case"": return ""
default: return character
}
}
///
public static func requestChange(_ character: Character) -> String {
if character.isLowercase {
return character.uppercased()
}
if character.isUppercase {
return character.lowercased()
}
if Set(["", "", "", "", "", "", "", ""]).contains(character) {
return String(kogaki(character))
}
if Set(["", "", "", "", "", "", "", ""]).contains(character) {
return String(ogaki(character))
}
if Set(["", "", "", "", "", "", "", "", "", "", "", "", "", ""]).contains(character) {
return String(dakuten(character))
}
if Set(["", "", "", "", "", "", "", "", "", "", "", "", "", ""]).contains(character) {
return String(mudakuten(character))
}
if Set(["", ""]).contains(character) {
return String(kogaki(character))
}
if Set(["", ""]).contains(character) {
return String(dakuten(ogaki(character)))
}
if Set(["", ""]).contains(character) {
return String(mudakuten(character))
}
if Set(["", "", "", "", ""]).contains(character) {
return String(dakuten(character))
}
if Set(["", "", "", "", ""]).contains(character) {
return String(handakuten(mudakuten(character)))
}
if Set(["", "", "", "", ""]).contains(character) {
return String(muhandakuten(character))
}
return String(character)
}
}
public extension Character {
/// Returns the Katakanized version of the character.
@inlinable func toKatakana() -> Character {
if self.unicodeScalars.count != 1 {
return self
}
let scalar = self.unicodeScalars.first!
if 0x3041 <= scalar.value && scalar.value <= 0x3096 {
return Character(UnicodeScalar(scalar.value + 96)!)
} else {
return self
}
}
/// Returns the Hiraganized version of the character.
@inlinable func toHiragana() -> Character {
if self.unicodeScalars.count != 1 {
return self
}
let scalar = self.unicodeScalars.first!
if 0x30A1 <= scalar.value && scalar.value <= 0x30F6 {
return Character(UnicodeScalar(scalar.value - 96)!)
} else {
return self
}
}
}