-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathhangul.go
106 lines (91 loc) · 2.31 KB
/
hangul.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2012, Homin Lee <[email protected]>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hangul provide handy tools for manipulate korean character:
// - Provide shorthands for korean consonants and vowels
// - Convert between jamo and compatibility-jamo
// - Split a character to it's three elements
// - Split multi element
// - Stroke count
package hangul
// IsHangul checks given rune is Hangul
func IsHangul(r rune) bool {
switch {
case 0xAC00 <= r && r <= 0xD7A3:
return true
case IsJaeum(r):
return true
case IsMoeum(r):
return true
}
return false
}
// Join converts NFD to NFC
func Join(l, m, t rune) rune {
// Convert if given rune is compatibility jamo
li, ok := leadIdx(Lead(l))
if !ok {
return rune(0xFFFD)
}
mi, ok := medialIdx(Medial(m))
if !ok {
return rune(0xFFFD)
}
ti, ok := tailIdx(Tail(t))
if !ok {
return rune(0xFFFD)
}
return rune(0xAC00 + (li*21+mi)*28 + ti)
}
// Split converts NFC to NFD
func Split(c rune) (l, m, t rune) {
t = (c - 0xAC00) % 28
m = ((c - 0xAC00 - t) % 588) / 28
l = (c - 0xAC00) / 588
l += leadBase
m += medialBase
if t != 0 {
t += tailBase - 1
}
return
}
// SplitCompat splits and returns l, m, t in compatibility jamo
func SplitCompat(c rune) (l, m, t rune) {
l, m, t = Split(c)
l = CompatJamo(l)
m = CompatJamo(m)
t = CompatJamo(t)
return
}
// EndsWithConsonant returns true if the given word ends with
// consonant(종성), false otherwise.
func EndsWithConsonant(word string) bool {
if LastConsonant(word) == 0 {
return false
}
return true
}
// LastConsonant returns last consonant(종성).
// It returns 0 if last consonant not exists.
func LastConsonant(word string) rune {
if word == "" {
return 0
}
runes := []rune(word)
_, _, t := Split(runes[len(runes)-1])
return t
}
// AppendPostposition returns word with postposition(조사).
// The 'with' will be appended to a word that ends with consonant, and
// the 'without' will be appended to a word that does not end with
// consonant.
func AppendPostposition(word, with, without string) string {
lastTail := LastConsonant(word)
if with == "으로" && lastTail == TailL {
return word + without // 로
}
if lastTail != 0 {
return word + with
}
return word + without
}