Created
September 13, 2025 07:20
-
-
Save 71/6283d525bd924672504bf5dfcde4dcc8 to your computer and use it in GitHub Desktop.
(Not tested)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Raw translation of | |
| // https://github.com/71/study-korean/blob/c4f3de22cd433c045458198956031f6edbb54f13/app/src/utils/korean.ts | |
| /// A Korean syllable. | |
| public struct KoreanSyllable: CustomStringConvertible { | |
| public let initialJamo: UnicodeScalar | |
| public let medialJamo: UnicodeScalar | |
| public let finalJamo: UnicodeScalar? | |
| /// Converts a Korean syllable such as 김 to its jamo ㄱㅣㅁ. | |
| public init?(_ syllable: Character) { | |
| guard let scalar = syllable.unicodeScalars.first, syllable.unicodeScalars.count == 1 else { | |
| return nil | |
| } | |
| self.init(scalar) | |
| } | |
| /// Converts a Korean syllable such as 김 to its jamo ㄱㅣㅁ. | |
| public init?(_ syllable: UnicodeScalar) { | |
| guard syllable.isKoreanSyllable else { return nil } | |
| let x = Int(syllable.value) - syllableBase | |
| let initialIndex = x / 28 / 21 | |
| let medialIndex = (x / 28) % 21 | |
| let finalIndex = x % 28 | |
| initialJamo = initial[initialIndex]! | |
| medialJamo = medial[medialIndex]! | |
| finalJamo = finalIndex == 0 ? nil : final[finalIndex - 1] | |
| } | |
| /// The jamo making up the syllable. | |
| public var description: String { | |
| if let finalJamo { | |
| "\(initialJamo)\(medialJamo)\(finalJamo)" | |
| } else { | |
| "\(initialJamo)\(medialJamo)" | |
| } | |
| } | |
| } | |
| extension Character { | |
| /// Whether this character is a Korean syllable such as 김. | |
| public var isKoreanSyllable: Bool { | |
| guard let scalar = unicodeScalars.first, unicodeScalars.count == 1 else { return false } | |
| return scalar.isKoreanSyllable | |
| } | |
| } | |
| extension UnicodeScalar { | |
| /// Whether this Unicode scalar is a Korean syllable such as 김. | |
| public var isKoreanSyllable: Bool { | |
| value >= 0xac00 && value <= 0xd7a3 | |
| } | |
| } | |
| /// First Unicode scalar representing a Korean syllable. | |
| private let syllableBase = 0xac00 | |
| private let initial = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ".utf16.map { UnicodeScalar($0) } | |
| private let medial = "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ".utf16.map { UnicodeScalar($0) } | |
| private let final = "ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ".utf16.map { UnicodeScalar($0) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment