kroman 1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5626c92e6ca422baa8e96587715da0597d279218
4
+ data.tar.gz: 2b039d3b0ef3a93a7353da23487390bf5a09b37b
5
+ SHA512:
6
+ metadata.gz: 2d6cdd57995bad6386307a1a52acc49d130044bafc34631e8171c2e2639cf0487bb17812a63e9540b510319729cc29aec926b25dd8d7129acdec35e6aa21bbbb
7
+ data.tar.gz: c66ca924176b3a1314d7d068ed87e398209aa3f757e5c1b2a290bed5ab055a4b086a8bb00f877fb8e5aa68586a725b7ff9b6c67b055591d287e603a70d1285af
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # kroman gem
2
+
3
+ The fantastic [kroman](https://github.com/cheunghy/kroman) converts hanguls to romanized syllables.
4
+
5
+ This is the ruby gem wrapper around it.
6
+
7
+ It has C extension, which means it's efficient, lightweight and enjoyable.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'kroman-gem'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install kroman-gem
24
+
25
+ ## Usage
26
+
27
+ ``` ruby
28
+ Kroman.let_me_sing!("손목시계")
29
+ => "son-mog-si-gye"
30
+ ```
31
+
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/cheunghy/kroman-gem.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
40
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+
3
+ create_makefile "kroman/kroman"
@@ -0,0 +1,48 @@
1
+ #include <ruby.h>
2
+ #include <unistd.h>
3
+ #include "kroman_convert.h"
4
+ #include "kroman_process.h"
5
+
6
+ static VALUE kroman_parse(VALUE self, VALUE hangul) {
7
+ VALUE hangul_s = rb_funcall(hangul, rb_intern("to_s"), 0);
8
+ char *hangul_content = RSTRING_PTR(hangul_s);
9
+ long hangul_length = RSTRING_LEN(hangul_s);
10
+
11
+ char in_file_name[L_tmpnam];
12
+ char out_file_name[L_tmpnam];
13
+
14
+ tmpnam(in_file_name);
15
+ tmpnam(out_file_name);
16
+ FILE *in_file = fopen(in_file_name, "w+");
17
+ FILE *out_file = fopen(out_file_name, "w+");
18
+
19
+ fwrite(hangul_content, hangul_length, 1, in_file);
20
+ fseek(in_file, 0, SEEK_SET);
21
+
22
+ kroman_process(in_file, out_file);
23
+
24
+ fseek(out_file, 0, SEEK_END);
25
+ long length = ftell(out_file);
26
+ fseek(out_file, 0, SEEK_SET);
27
+ char *buffer = malloc(length + 1);
28
+
29
+ fread(buffer, 1, length, out_file);
30
+ buffer[length] = 0;
31
+
32
+ fclose(in_file);
33
+ fclose(out_file);
34
+
35
+ unlink(in_file_name);
36
+ unlink(out_file_name);
37
+
38
+ VALUE romanized = rb_str_new_cstr(buffer);
39
+ return romanized;
40
+ }
41
+
42
+ void Init_kroman(void) {
43
+ VALUE cKroman;
44
+ cKroman = rb_const_get(rb_cObject, rb_intern("Kroman"));
45
+
46
+ rb_define_singleton_method(cKroman, "parse", kroman_parse, 1);
47
+ rb_define_singleton_method(cKroman, "let_me_sing!", kroman_parse, 1);
48
+ }
@@ -0,0 +1,297 @@
1
+ #include "kroman_convert.h"
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #define KROMAN_GA 0xac00
5
+ #define KROMAN_HIH 0xd7a3
6
+ #define KROMAN_HEAD_INTERVAL 588
7
+ #define KROMAN_BODY_INTERVAL 28
8
+ #define KROMAN_TAIL_INTERVAL 1
9
+ /*
10
+ * Referenced from
11
+ * http://www.programminginkorean.com/programming/hangul-in-unicode
12
+ * http://www.programminginkorean.com/programming/hangul-in-unicode/hangul-syllables-uac00-ud7a3/
13
+ * Many thanks!
14
+ *
15
+ * heads interval 588, total 19
16
+ * g gg n d dd r m b bb s ss ng(0) j jj c k t p h
17
+ * bodies interval 28, total 21
18
+ * a ae ya yae eo e yeo ye o wa wae oe yo u weo we wi yu eu eui i
19
+ * tails interval 1, total 28
20
+ * 0 g gg gs n nj nh d r rk rm rb rs rt rp rh m b bs s ss ng j c k t p h
21
+ *
22
+ * starts at U+AC00, ends at U+D7A3
23
+ */
24
+
25
+ void kroman_head_from_index(int, char *);
26
+ void kroman_body_from_index(int, char *);
27
+ void kroman_tail_from_index(int, char *);
28
+
29
+ void kroman_convert(wchar_t character, char *retstring, bool *is_hangul) {
30
+ int char_int = (int)character;
31
+ // If it is hangul
32
+ if ((char_int >= KROMAN_GA) && (char_int <= KROMAN_HIH)) {
33
+ int head_index = (char_int - KROMAN_GA) / KROMAN_HEAD_INTERVAL;
34
+ int head_lefto = (char_int - KROMAN_GA) % KROMAN_HEAD_INTERVAL;
35
+ int body_index = head_lefto / KROMAN_BODY_INTERVAL;
36
+ int tail_index = head_lefto % KROMAN_BODY_INTERVAL;
37
+ char head_string[10];
38
+ kroman_head_from_index(head_index, head_string);
39
+ char body_string[10];
40
+ kroman_body_from_index(body_index, body_string);
41
+ char tail_string[10];
42
+ kroman_tail_from_index(tail_index, tail_string);
43
+ strcat(retstring, head_string);
44
+ strcat(retstring, body_string);
45
+ strcat(retstring, tail_string);
46
+ *is_hangul = true;
47
+ } else { // else normal wide char
48
+ wchar_t wchar_string[2];
49
+ wchar_string[0] = character;
50
+ wchar_string[1] = 0;
51
+ wcstombs(retstring, (const wchar_t *)wchar_string, 6);
52
+ *is_hangul = false;
53
+ }
54
+ }
55
+
56
+ void kroman_head_from_index(int head_index, char *retstring) {
57
+ char *head_string;
58
+
59
+ switch(head_index) {
60
+ case 0:
61
+ head_string = "g";
62
+ break;
63
+ case 1:
64
+ head_string = "gg";
65
+ break;
66
+ case 2:
67
+ head_string = "n";
68
+ break;
69
+ case 3:
70
+ head_string = "d";
71
+ break;
72
+ case 4:
73
+ head_string = "dd";
74
+ break;
75
+ case 5:
76
+ head_string = "r";
77
+ break;
78
+ case 6:
79
+ head_string = "m";
80
+ break;
81
+ case 7:
82
+ head_string = "b";
83
+ break;
84
+ case 8:
85
+ head_string = "bb";
86
+ break;
87
+ case 9:
88
+ head_string = "s";
89
+ break;
90
+ case 10:
91
+ head_string = "ss";
92
+ break;
93
+ case 11:
94
+ head_string = "";
95
+ break;
96
+ case 12:
97
+ head_string = "j";
98
+ break;
99
+ case 13:
100
+ head_string = "jj";
101
+ break;
102
+ case 14:
103
+ head_string = "c";
104
+ break;
105
+ case 15:
106
+ head_string = "k";
107
+ break;
108
+ case 16:
109
+ head_string = "t";
110
+ break;
111
+ case 17:
112
+ head_string = "p";
113
+ break;
114
+ case 18:
115
+ head_string = "h";
116
+ break;
117
+ default:
118
+ fprintf(stderr, "Error: Unknown head.\n");
119
+ exit(1);
120
+ break;
121
+ }
122
+
123
+ sprintf(retstring, "%s", head_string);
124
+ }
125
+
126
+ void kroman_body_from_index(int body_index, char *retstring) {
127
+ char *body_string;
128
+
129
+ switch(body_index) {
130
+ case 0:
131
+ body_string = "a";
132
+ break;
133
+ case 1:
134
+ body_string = "ae";
135
+ break;
136
+ case 2:
137
+ body_string = "ya";
138
+ break;
139
+ case 3:
140
+ body_string = "yae";
141
+ break;
142
+ case 4:
143
+ body_string = "eo";
144
+ break;
145
+ case 5:
146
+ body_string = "e";
147
+ break;
148
+ case 6:
149
+ body_string = "yeo";
150
+ break;
151
+ case 7:
152
+ body_string = "ye";
153
+ break;
154
+ case 8:
155
+ body_string = "o";
156
+ break;
157
+ case 9:
158
+ body_string = "wa";
159
+ break;
160
+ case 10:
161
+ body_string = "wae";
162
+ break;
163
+ case 11:
164
+ body_string = "oe";
165
+ break;
166
+ case 12:
167
+ body_string = "yo";
168
+ break;
169
+ case 13:
170
+ body_string = "u";
171
+ break;
172
+ case 14:
173
+ body_string = "weo";
174
+ break;
175
+ case 15:
176
+ body_string = "we";
177
+ break;
178
+ case 16:
179
+ body_string = "wi";
180
+ break;
181
+ case 17:
182
+ body_string = "yu";
183
+ break;
184
+ case 18:
185
+ body_string = "eu";
186
+ break;
187
+ case 19:
188
+ body_string = "eui";
189
+ break;
190
+ case 20:
191
+ body_string = "i";
192
+ break;
193
+ default:
194
+ fprintf(stderr, "Error: unknown body\n");
195
+ exit(1);
196
+ break;
197
+ }
198
+
199
+ sprintf(retstring, "%s", body_string);
200
+ }
201
+
202
+ void kroman_tail_from_index(int tail_index, char *retstring) {
203
+ char *tail_string;
204
+
205
+ switch(tail_index) {
206
+ case 0:
207
+ tail_string = "";
208
+ break;
209
+ case 1:
210
+ tail_string = "g";
211
+ break;
212
+ case 2:
213
+ tail_string = "gg";
214
+ break;
215
+ case 3:
216
+ tail_string = "gs";
217
+ break;
218
+ case 4:
219
+ tail_string = "n";
220
+ break;
221
+ case 5:
222
+ tail_string = "nj";
223
+ break;
224
+ case 6:
225
+ tail_string = "nh";
226
+ break;
227
+ case 7:
228
+ tail_string = "d";
229
+ break;
230
+ case 8:
231
+ tail_string = "r";
232
+ break;
233
+ case 9:
234
+ tail_string = "rk";
235
+ break;
236
+ case 10:
237
+ tail_string = "rm";
238
+ break;
239
+ case 11:
240
+ tail_string = "rb";
241
+ break;
242
+ case 12:
243
+ tail_string = "rs";
244
+ break;
245
+ case 13:
246
+ tail_string = "rt";
247
+ break;
248
+ case 14:
249
+ tail_string = "rp";
250
+ break;
251
+ case 15:
252
+ tail_string = "rh";
253
+ break;
254
+ case 16:
255
+ tail_string = "m";
256
+ break;
257
+ case 17:
258
+ tail_string = "b";
259
+ break;
260
+ case 18:
261
+ tail_string = "bs";
262
+ break;
263
+ case 19:
264
+ tail_string = "s";
265
+ break;
266
+ case 20:
267
+ tail_string = "ss";
268
+ break;
269
+ case 21:
270
+ tail_string = "ng";
271
+ break;
272
+ case 22:
273
+ tail_string = "j";
274
+ break;
275
+ case 23:
276
+ tail_string = "c";
277
+ break;
278
+ case 24:
279
+ tail_string = "k";
280
+ break;
281
+ case 25:
282
+ tail_string = "t";
283
+ break;
284
+ case 26:
285
+ tail_string = "p";
286
+ break;
287
+ case 27:
288
+ tail_string = "h";
289
+ break;
290
+ default:
291
+ fprintf(stderr, "Error: unknown tail\n");
292
+ exit(1);
293
+ break;
294
+ }
295
+
296
+ sprintf(retstring, "%s", tail_string);
297
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef KROMAN_CONVERT_H__
2
+ #define KROMAN_CONVERT_H__
3
+
4
+ #include <wchar.h>
5
+ #include <stdbool.h>
6
+
7
+ void kroman_convert(wchar_t, char *, bool *);
8
+
9
+ #endif /* KROMAN_CONVERT_H__ */
@@ -0,0 +1,50 @@
1
+ #include "kroman_process.h"
2
+ #include "kroman_convert.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+ #include <wchar.h>
7
+ #include <locale.h>
8
+ #include <stdbool.h>
9
+
10
+ #define KROMAN_MAXLINE 4096
11
+ #define KROMAN_SIZE 20
12
+
13
+ void kroman_process_line(char *user_line, FILE *outstream);
14
+
15
+ void kroman_process(FILE *instream, FILE *outstream) {
16
+ // Set current user locale, may or may not be en_US.UTF-8
17
+ setlocale(LC_ALL, "");
18
+ char *user_line = malloc(KROMAN_MAXLINE * sizeof(char));
19
+ while (fgets(user_line, KROMAN_MAXLINE, instream)) {
20
+ kroman_process_line(user_line, outstream);
21
+ }
22
+ free(user_line);
23
+ if (ferror(instream)) {
24
+ printf("Instream error occured!\n");
25
+ exit(1);
26
+ }
27
+ }
28
+
29
+ void kroman_process_line(char *user_line, FILE *outstream) {
30
+ wchar_t *wide_line = malloc(KROMAN_MAXLINE * sizeof(wchar_t));
31
+ mbstowcs(wide_line, user_line, KROMAN_MAXLINE);
32
+ size_t len = wcslen(wide_line);
33
+ bool last_is_hangul = false;
34
+ for (size_t i = 0; i < len; ++i) {
35
+ wchar_t wide_char = wide_line[i];
36
+ char *retstring = malloc(sizeof(char) * KROMAN_SIZE);
37
+ memset(retstring, 0, sizeof(char) * KROMAN_SIZE);
38
+ bool is_hangul;
39
+ kroman_convert(wide_char, retstring, &is_hangul);
40
+ if (last_is_hangul && is_hangul) {
41
+ fprintf(outstream, "-%s", retstring);
42
+ } else {
43
+ fprintf(outstream, "%s", retstring);
44
+ }
45
+
46
+ last_is_hangul = is_hangul;
47
+ free(retstring);
48
+ }
49
+ free(wide_line);
50
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef KROMAN_PROCESS_H__
2
+ #define KROMAN_PROCESS_H__
3
+
4
+ #include <stdio.h>
5
+
6
+ void kroman_process(FILE *, FILE *);
7
+
8
+ #endif /* KROMAN_PROCESS_H__ */
data/kroman.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'kroman/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "kroman"
9
+ spec.version = Kroman::VERSION
10
+ spec.authors = ["Zhang Kai Yu"]
11
+ spec.email = ["yeannylam@gmail.com"]
12
+
13
+ spec.summary = "Kroman converts Korean hangul to romanized syllables"
14
+ spec.description = "Kroman make nice Korean songs singable"
15
+ spec.homepage = "https://github.com/cheunghy/kroman-gem"
16
+ spec.license = "MIT"
17
+
18
+ spec.extensions = %w[ext/kroman/extconf.rb]
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ end
@@ -0,0 +1,3 @@
1
+ module Kroman
2
+ VERSION = 1.0
3
+ end
data/lib/kroman.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Kroman
2
+ require 'kroman/kroman'
3
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kroman
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Zhang Kai Yu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Kroman make nice Korean songs singable
42
+ email:
43
+ - yeannylam@gmail.com
44
+ executables: []
45
+ extensions:
46
+ - ext/kroman/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - README.md
52
+ - Rakefile
53
+ - ext/kroman/extconf.rb
54
+ - ext/kroman/kroman.c
55
+ - ext/kroman/kroman_convert.c
56
+ - ext/kroman/kroman_convert.h
57
+ - ext/kroman/kroman_process.c
58
+ - ext/kroman/kroman_process.h
59
+ - kroman.gemspec
60
+ - lib/kroman.rb
61
+ - lib/kroman/version.rb
62
+ homepage: https://github.com/cheunghy/kroman-gem
63
+ licenses:
64
+ - MIT
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.4.5
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Kroman converts Korean hangul to romanized syllables
86
+ test_files: []
87
+ has_rdoc: