ununiga 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41a97f562ee21f2e971b08d2e523f3150d4d89b1
4
- data.tar.gz: 7dcabeb9592a94b6280146dd05d8ede68607b5ef
3
+ metadata.gz: b8ed609a7765abb9b795d537e32fb9fbbb0c311d
4
+ data.tar.gz: 1cb2c593186f7c6ef0f741198738e0ee88d16ab0
5
5
  SHA512:
6
- metadata.gz: 2c43f16e62863f91d239c9225770c0d11dfcf7e15664f07e54d7205b26e7e9b7d4d33f7fa62f72575a2eebbed8feb73be634c9cba05312fb5e0e4ee52352b78a
7
- data.tar.gz: dceba36eba34b7c0437a1268bedbbcf9bedde4caed795a11c72383d432f464c38a3eef8af3f7432c17240e0b3c64b77e5a42a46ff42d950ff29cfcf62484cd7a
6
+ metadata.gz: 0b006f84c3b58d5b05e82af55f1633385ec6cb97d7caca032585eb26b5dffe69e77cbf5a82f93f51442e4ba1da2b2af49bb31ba8bc94a200a87f15f21b4f45cf
7
+ data.tar.gz: aa05c9c954390447392d858fc7ca10104cfa7f02bc5cadde5275afca9670a0f5ba31f4d7bc766534e0b192a81b5335c4ebefa6ebfa282d2a1527ed0cceec6775
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.2.0
7
+ - 2.3.0
8
+
9
+ before_install:
10
+ - gem install i18n --no-rdoc --no-ri --no-document
11
+
12
+ script: rake test
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ununiga (1.0.1)
5
+
6
+ GEM
7
+ remote: http://www.rubygems.org/
8
+ specs:
9
+ i18n (0.7.0)
10
+ minitest (5.8.3)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ i18n
17
+ minitest
18
+ ununiga!
19
+
20
+ BUNDLED WITH
21
+ 1.11.2
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ [![Build Status](https://travis-ci.org/keepcosmos/ununiga.svg?branch=master)](https://travis-ci.org/keepcosmos/ununiga)
2
+ [![Gem Version](https://badge.fury.io/rb/ununiga.svg)](https://badge.fury.io/rb/ununiga)
3
+
4
+ # ununiga[은는이가]
5
+
6
+ 은는이가는 한글의 자소분리를 분리하고 조사를 찾아주는 역할을 합니다.
7
+ I18n의 Backend 모듈도 제공합니다.
8
+
9
+ ## Installation
10
+ ```
11
+ gem install ununiga
12
+ ```
13
+
14
+ ### 조사 찾기
15
+ ```ruby
16
+ require 'ununiga'
17
+
18
+ Ununiga::JosaPicker.takewell("레일즈와(과) 쟝고은(는) 싸우지 않습니다.")
19
+ # => "레일즈와 쟝고는 싸우지 않습니다."
20
+ Ununiga::JosaPicker.takewell("트위터(으)로 로그인합니다.")
21
+ # => "페이스북로 로그인합니다."
22
+
23
+ picker = Ununiga::JosaPicker.new("레일즈은(는) 루비을(를) 사용합니다.")
24
+ picker.takewell
25
+ # => "레일즈는 루비를 사용합니다.
26
+
27
+ picker.josas
28
+ # => [[3, ["은", "는"]], [10, ["을", "를"]]]
29
+ ```
30
+
31
+ ### I18n에 적용하기
32
+ 1. Gemfile에 ununiga를 추가합니다.
33
+ ```
34
+ gem 'ununiga'
35
+ ```
36
+
37
+ 2. Initializer나 environment config파일에 아래 코드를 추가합니다.
38
+ ```ruby
39
+ I18n::Backend::Simple.send(:include, Ununiga::I18n::JosaTransformer)
40
+ ```
41
+
42
+ 3. 한글 locale yml 파일에 조사를 사용하는 부분을 찾아 '은(는)|(는)은|을(를)...'등으로 조사를 변경합니다.
43
+ ```yaml
44
+ links:
45
+ sign_in_with_provider: "%{provider}(으)로 로그인"
46
+
47
+ # Rails의 ActiveModel/ActiveRecord의 Validation을 사용할 경우
48
+ errors:
49
+ # 디폴트는 `%{attribute} %{message}`형식으로 띄워쓰기가 되어 있으며로 format을 붙여쓰기로 변경해줍니다.
50
+ foramt: "%{attribute}%{message}"
51
+ messages:
52
+ accepted: 을(를) 반드시 확인해야 합니다.
53
+ equal_to: 은(는) %{count}와(과) 같아야 합니다
54
+ ```
55
+
56
+ ### 자소 분리하기
57
+ ```ruby
58
+ splitter = Ununiga::JasoSplitter.new('흯')
59
+ splitter.chosung # => 'ㅎ'
60
+ splitter.jungsung # => 'ㅢ'
61
+ splitter.jongsung # => 'ㄳ'
62
+ splitter.split # => ['ㅎ', 'ㅢ', 'ㄳ']
63
+ ```
64
+
65
+ ## Test
66
+ 두가지 방식으로 테스트 할 수 있습니다.
67
+ * `rake test` 혹은 그냥 `rake` 커맨드를 사용합니다.
68
+ * 특정 파일을 테스트할 경우 `ruby -Ilib:test /test/{file_name}` 을 사용합니다.
69
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc 'Run tests'
8
+ task default: :test
@@ -0,0 +1,16 @@
1
+ require 'ununiga/josa_picker'
2
+
3
+ module Ununiga::I18n
4
+ module JosaTransformer
5
+ def translate(*args)
6
+ transform(super)
7
+ end
8
+
9
+ def transform(entry)
10
+ if !entry.is_a?(Hash) && I18n.locale.to_s =~ /ko|ko_KR/i
11
+ return Ununiga::JosaPicker.new(entry).takewell
12
+ end
13
+ entry
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ module Ununiga
2
+ # 한글 자소분리 클래스
3
+ # 1개의 한글 문자를 초성/중성/종성으로 분리한다.
4
+ #
5
+ # Sample:
6
+ #
7
+ # splitter = Ununiga::JasoSplitter.new('흯')
8
+ # splitter.extract_chosung # => 'ㅎ'
9
+ # splitter.extract_jungsung # => 'ㅢ'
10
+ # splitter.extract_jongsung # => 'ㄳ'
11
+ # splitter.split # => ['ㅎ', 'ㅢ', 'ㄳ']
12
+ #
13
+ # # 종성이 없는 경우는 nil
14
+ # splitter2 = Ununiga::JasoSplitter.new('가')
15
+ # splitter2.extract_jongsung # => nil
16
+ # splitter2.split # => ['ㄱ', 'ㅏ', nil]
17
+ #
18
+ class JasoSplitter
19
+ CHOSUNGS = %w(ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ).freeze
20
+ JUNGSUNGS = %w(ㅏ ㅐ ㅑ ㅒ ㅓ ㅔ ㅕ ㅖ ㅗ ㅘ ㅛ ㅙ ㅚ ㅜ ㅝ ㅞ ㅟ ㅠ ㅡ ㅢ ㅣ).freeze
21
+ JONGSUNGS = %w(ㄱ ㄲ ㄳ ㄴ ㄵ ㄶ ㄷ ㄹ ㄺ ㄻ ㄼ ㄽ ㄾ ㄿ ㅀ ㅁ ㅂ ㅄ ㅅ ㅆ ㅇ ㅈ ㅊ ㅋ ㅌ ㅍ ㅎ).unshift(nil).freeze
22
+ KR_RANGE = ('가'.unpack('U')[0]..'힣'.unpack('U')[0]).freeze
23
+ KR_OFFSET = KR_RANGE.first.freeze
24
+
25
+ attr_reader :kr_char
26
+
27
+ def initialize(kr_char)
28
+ fail ArgumentError, 'Argument must be single character' unless kr_char.size == 1
29
+ @kr_char = kr_char
30
+ end
31
+
32
+ def split
33
+ [extract_chosung, extract_jungsung, extract_jongsung]
34
+ end
35
+
36
+ def extract_chosung
37
+ nil unless korean?
38
+ CHOSUNGS[kr_relative_code / (JUNGSUNGS.size * JONGSUNGS.size)]
39
+ end
40
+
41
+ def extract_jungsung
42
+ nil unless korean?
43
+ JUNGSUNGS[kr_relative_code % (JUNGSUNGS.size * JONGSUNGS.size) / JONGSUNGS.size]
44
+ end
45
+
46
+ def extract_jongsung
47
+ nil unless korean?
48
+ JONGSUNGS[kr_relative_code % JONGSUNGS.size]
49
+ end
50
+
51
+ def korean?
52
+ KR_RANGE.cover?(kr_code)
53
+ end
54
+
55
+ [:chosung, :jungsung, :jongsung].each do |m|
56
+ alias_method m, :"extract_#{m}"
57
+ end
58
+
59
+ private
60
+
61
+ def kr_code
62
+ kr_char.unpack('U')[0]
63
+ end
64
+
65
+ def kr_relative_code
66
+ kr_code - KR_OFFSET
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,65 @@
1
+ require 'ununiga/jaso_splitter'
2
+
3
+ module Ununiga
4
+ # 한글 초성, 중성, 종성 분리기
5
+ class JosaPicker
6
+ JOSAS = [%w(은 는),
7
+ %w(이 가),
8
+ %w(을 를),
9
+ %w(과 와),
10
+ %w(으로 로)
11
+ ].freeze
12
+
13
+ attr_reader :korean_str
14
+
15
+ class << self
16
+ def takewell(str)
17
+ new(str).takewell
18
+ end
19
+ end
20
+
21
+ def initialize(str)
22
+ @korean_str = str
23
+ end
24
+
25
+ def takewell
26
+ korean_str.gsub josa_regexp do |matched|
27
+ index = $~.offset(0)[0]
28
+ next if index == 0
29
+ josa = JOSAS.find { |josa| josa_convension(josa).include? matched }
30
+ splitter = JasoSplitter.new(korean_str[index - 1])
31
+ josa[(splitter.jongsung ? 0 : 1)]
32
+ end
33
+ end
34
+
35
+ def josas
36
+ res = []
37
+ korean_str.scan josa_regexp do |matched|
38
+ res << [$~.offset(0)[0], JOSAS.find { |josa| josa.include? matched[0] }]
39
+ end
40
+ res
41
+ end
42
+
43
+ private
44
+
45
+ def josa_regexp
46
+ @_josa_regexp ||=
47
+ begin
48
+ josa_regexp_seq = JOSAS.map do |josa|
49
+ conv = josa_convension(josa)
50
+ conv.map { |str| str.gsub!('(', '\\(').gsub!(')', '\\)') }
51
+ end
52
+ Regexp.new(josa_regexp_seq.flatten.join('|'))
53
+ end
54
+ end
55
+
56
+ # JOSAS의 element가 온다.
57
+ def josa_convension(josa)
58
+ if josa[0].size == 1
59
+ ["#{josa[0]}(#{josa[1]})", "#{josa[1]}(#{josa[0]})"]
60
+ elsif josa[0].size == 2
61
+ ["(#{josa[0][0]})#{josa[1]}"]
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ module Ununiga
2
+ VERSION = '1.0.3'
3
+ end
data/test/test.yml ADDED
@@ -0,0 +1,5 @@
1
+ ko:
2
+ someone_pay: '%{name}이(가) 돈을 냅니다.'
3
+ someone_eat_something: '%{name}은(는) %{meal}을(를) 먹습니다.'
4
+ do_something_with_someone: '%{name1}와(과) %{name2}은(는) %{doing}을(를) 합니다.'
5
+
@@ -0,0 +1,63 @@
1
+ require 'minitest/autorun'
2
+ require 'ununiga/jaso_splitter'
3
+
4
+ class JamoSplitterTest < Minitest::Unit::TestCase
5
+ def test_extract_chosung
6
+ testgroup = { '가' => 'ㄱ',
7
+ '낳' => 'ㄴ',
8
+ '짷' => 'ㅉ',
9
+ '하' => 'ㅎ'
10
+ }
11
+ testgroup.each do |char, chosung|
12
+ splitter = Ununiga::JasoSplitter.new(char)
13
+ assert_equal chosung, splitter.extract_chosung
14
+ end
15
+ end
16
+
17
+ def test_extract_jungsung
18
+ testgroup = { '가' => 'ㅏ',
19
+ '내' => 'ㅐ',
20
+ '찋' => 'ㅢ',
21
+ '휷' => 'ㅠ'
22
+ }
23
+ testgroup.each do |char, jungsung|
24
+ splitter = Ununiga::JasoSplitter.new(char)
25
+ assert_equal jungsung, splitter.extract_jungsung
26
+ end
27
+ end
28
+
29
+ def test_extract_jongsung
30
+ testgroup = { '가' => nil,
31
+ '내' => nil,
32
+ '찋' => 'ㅎ',
33
+ '휷' => 'ㄳ'
34
+ }
35
+ testgroup.each do |char, jongsung|
36
+ splitter = Ununiga::JasoSplitter.new(char)
37
+ assert_equal jongsung, splitter.extract_jongsung
38
+ end
39
+ end
40
+
41
+ def test_split
42
+ testgroup = { '신' => ['ㅅ', 'ㅣ', 'ㄴ'],
43
+ '재' => ['ㅈ', 'ㅐ', nil],
44
+ '현' => ['ㅎ', 'ㅕ', 'ㄴ']
45
+ }
46
+ testgroup.each do |char, splitted|
47
+ splitter = Ununiga::JasoSplitter.new(char)
48
+ assert_equal splitted, splitter.split
49
+ end
50
+ end
51
+
52
+ def test_non_korean_exception
53
+ %w(a 中 च Қ に).each do |char|
54
+ assert !Ununiga::JasoSplitter.new(char).korean?
55
+ end
56
+ end
57
+
58
+ def test_non_single_character_exception
59
+ assert_raises ArgumentError do
60
+ Ununiga::JasoSplitter.new('두글자')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,32 @@
1
+ require 'minitest/autorun'
2
+ require 'ununiga/josa_picker'
3
+
4
+ class JosaPickerTest < Minitest::Unit::TestCase
5
+ def test_takewell
6
+ assert_equal '철수가 개발을 좋아합니다.', takewell('철수이(가) 개발을(를) 좋아합니다.')
7
+
8
+ assert_equal '레일즈는 루비를 사용합니다.', takewell('레일즈은(는) 루비을(를) 사용합니다.')
9
+ assert_equal '레일즈는 루비를 사용합니다.', takewell('레일즈는(은) 루비를(을) 사용합니다.')
10
+
11
+ assert_equal '레일즈와 쟝고는 싸우지 않습니다.', takewell('레일즈와(과) 쟝고은(는) 싸우지 않습니다.')
12
+
13
+ assert_equal '페이스북으로부터 인증되었습니다.', takewell('페이스북(으)로부터 인증되었습니다.')
14
+ assert_equal '트위터로부터 인증되었습니다.', takewell('트위터(으)로부터 인증되었습니다.')
15
+ end
16
+
17
+ def test_find_josas
18
+ str1 = '철수이(가) 개발을(를) 좋아합니다.'
19
+ assert_equal [[2, %w(이 가)], [9, %w(을 를)]], find_josas(str1)
20
+
21
+ str2 = '레일즈은(는) 루비을(를) 사용합니다.'
22
+ assert_equal [[3, %w(은 는)], [10, %w(을 를)]], find_josas(str2)
23
+ end
24
+
25
+ def find_josas(str)
26
+ Ununiga::JosaPicker.new(str).josas
27
+ end
28
+
29
+ def takewell(str)
30
+ Ununiga::JosaPicker.new(str).takewell
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require 'minitest/autorun'
2
+ require 'i18n'
3
+ require 'ununiga/i18n/josa_transformer'
4
+
5
+ class JosaTransformerTest < Minitest::Unit::TestCase
6
+ def setup
7
+ super
8
+ I18n::Backend::Simple.send(:include, Ununiga::I18n::JosaTransformer)
9
+ I18n.load_path = [File.dirname(__FILE__) + '/test.yml']
10
+ I18n.available_locales = [:en, :ko, :ko_KR]
11
+ I18n.locale = :ko
12
+ end
13
+
14
+ def test_transform_korean
15
+ assert_equal '철수가 돈을 냅니다.', I18n.t(:someone_pay, name: '철수')
16
+ assert_equal '재현이 돈을 냅니다.', I18n.t(:someone_pay, name: '재현')
17
+
18
+ assert_equal '호랑이는 사과를 먹습니다.', I18n.t(:someone_eat_something, name: '호랑이', meal: '사과')
19
+ assert_equal '곰은 마늘을 먹습니다.', I18n.t(:someone_eat_something, name: '곰', meal: '마늘')
20
+
21
+ assert_equal '재현과 진아는 개발을 합니다.', I18n.t(:do_something_with_someone, name1: '재현', name2: '진아', doing: '개발')
22
+ assert_equal '정하와 민정은 디자인을 합니다.', I18n.t(:do_something_with_someone, name1: '정하', name2: '민정', doing: '디자인')
23
+ end
24
+
25
+
26
+ end
data/ununiga.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'ununiga'
3
+ s.version = '1.0.3'
4
+ s.date = '2016-01-25'
5
+ s.summary = 'Support Jaso and Josa(Korean Language specific function)'
6
+ s.description = '한글 자소 분리 및 적절한 조사를 찾아주어 번역해줍니다.'
7
+ s.authors = ['Jaehyun Shin']
8
+ s.email = 'keepcosmos@gmail.com'
9
+ s.files = ['lib/ununiga.rb']
10
+ s.homepage = 'https://github.com/keepcosmos/ununiga'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.require_paths = ["lib"]
13
+ s.add_development_dependency 'i18n'
14
+ s.add_development_dependency 'minitest'
15
+ s.license = 'MIT'
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ununiga
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaehyun Shin
@@ -44,7 +44,22 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
+ - ".gitignore"
48
+ - ".travis.yml"
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - README.md
52
+ - Rakefile
47
53
  - lib/ununiga.rb
54
+ - lib/ununiga/i18n/josa_transformer.rb
55
+ - lib/ununiga/jaso_splitter.rb
56
+ - lib/ununiga/josa_picker.rb
57
+ - lib/ununiga/version.rb
58
+ - test/test.yml
59
+ - test/test_jaso_splitter.rb
60
+ - test/test_josa_picker.rb
61
+ - test/test_josa_transformer.rb
62
+ - ununiga.gemspec
48
63
  homepage: https://github.com/keepcosmos/ununiga
49
64
  licenses:
50
65
  - MIT