me2text-ruby 1.0.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.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ .yardoc
4
+ Gemfile.lock
5
+ doc/*
6
+ pkg/*
7
+ perf/*
8
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in me2text-ruby.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2012 NHN Corp.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ me2text-ruby, me2text parser for ruby
2
+ ======================================
3
+
4
+ me2text-ruby는 me2text 형식의 문자열을 HTML 또는 평문(plain text)로 변환해주는
5
+ ruby 라이브러리이다.
6
+
7
+ 사용
8
+ ----
9
+
10
+ ### HTML로 변환
11
+
12
+ require 'me2text'
13
+
14
+ str = 'me2text는 "미투데이(TM)":http://me2day.net 의 글/댓글 작성 규칙이다.'
15
+ Me2Text.me2text(str)
16
+ # => me2text는 <a href='http://me2day.net'>미투데이™"</a>의 글/댓글 작성 규칙이다.
17
+
18
+ ### 평문으로 변환
19
+
20
+ require 'me2text'
21
+
22
+ str = 'me2text는 "미투데이(TM)":http://me2day.net 의 글/댓글 작성 규칙이다.'
23
+ Me2Text.me2text(str, :text)
24
+ # => me2text는 미투데이™"의 글/댓글 작성 규칙이다.
25
+
26
+ ### String 클래스 확장
27
+
28
+ require 'me2text/string_ext'
29
+
30
+ str = 'me2text는 "미투데이(TM)":http://me2day.net 의 글/댓글 작성 규칙이다.'
31
+ str.me2text
32
+ # => me2text는 <a href='http://me2day.net'>미투데이™"</a>의 글/댓글 작성 규칙이다.
33
+
34
+ ### 주의 사항
35
+
36
+ me2text-ruby 사용을 위해서는 $KCODE 변수를 'UTF8' 또는 'u'로 지정해야 한다.
37
+
38
+ $KCODE = 'UTF8'
39
+
40
+ me2text-ruby는 ruby 1.8.7-p302에서 테스트되었으며 아직 ruby 1.9.X를 지원하지 않는다.
41
+
42
+ 설치
43
+ ----
44
+ me2text-ruby 라이브러리는 RubyGems를 통해 설치할 수 있다.
45
+
46
+ gem install me2text-ruby
47
+
48
+
49
+ me2text란?
50
+ ----------
51
+ me2text는 미투데이 글/댓글등의 글 작성 규칙을 일컫는다.
52
+
53
+ ### 링크
54
+
55
+ 링크를 표현하는 형식은 다음과 같다
56
+
57
+ "링크를 걸 문구":URL
58
+
59
+ 예를 들면 다음과 같다.
60
+
61
+ 미투텍스트는 "미투데이":http://me2day.net 의 글/댓글 작성 규칙을 일컫는다.
62
+ => 미투텍스트는 <a href='http://me2day.net'>미투데이"</a>의 글/댓글 작성 규칙을 일컫는다.
63
+
64
+ 또, 이와 같은 링크 형식으로 작성되지 않더라도 단순히 URL만 지정한 경우에 대해서도 링크로
65
+ 변환한다.
66
+
67
+ `자세한 내용은 이 주소로. http://me2day.net`
68
+ => `자세한 내용은 이 주소로. <a href='http://me2day.net'>http://me2day.net</a>`
69
+
70
+ 백슬래시를 사용해 링크를 걸 문구에 따옴표를 포함할 수 있다. 즉, 아래와 같은 링크를 지정한
71
+ 문자열에서 링크를 걸 문구에 포함된 따옴표에는 백슬래시를 붙여 전체 문자열에 링크를 적용할
72
+ 수 있다.
73
+
74
+ "레이디가가 소감, \"한국의 환대 따뜻하고 신나, 그리웠다\"":http://me2.do/FnlH8u3
75
+ => <a href='http://me2.do/FnlH8u3'>레이디가가 소감, “한국의 환대 따뜻하고 신나, 그리웠다”</a>
76
+
77
+ ### 따옴표
78
+
79
+ 다음과 같이 따옴표 문자를 LEFT/RIGHT DOUBLE QUOTATION MARK(“”) 문자로 변환한다.
80
+
81
+ "안녕하세요" -> “안녕하세요”
82
+
83
+ ### 심볼 문자의 표현
84
+
85
+ 다음과 같은 특정 순서의 문자열을 심볼 문자로 변환한다.
86
+
87
+ * ... => … (HORIZONTAL ELLIPSIS)
88
+ * (TM) => ™ (TRADE MARK SIGN)
89
+ * (R) => ® (REGISTERED SIGN)
90
+ * (C) => © (COPYRIGHT SIGN)
91
+ * -- => — (EN DASH)
92
+
93
+ TODO
94
+ ----
95
+
96
+ * Ruby 1.9 지원
97
+
98
+ Copyright and License
99
+ ---------------------
100
+
101
+ Copyright 2012 NHN Corp.
102
+
103
+ me2text is released under the MIT license:
104
+
105
+ * www.opensource.org/licenses/MIT
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,108 @@
1
+ # encoding: utf-8
2
+
3
+ require 'me2text/token'
4
+
5
+ # Public: me2text 변환 메소드 제공한다.
6
+ #
7
+ # Examples
8
+ #
9
+ # require 'me2text'
10
+ #
11
+ # str = 'me2text는 "미투데이(TM)":http://me2day.net 의 글/댓글 작성 규칙이다.'
12
+ # Me2Text.me2text(str)
13
+ # # => me2text는 <a href='http://me2day.net'>미투데이™"</a>의 글/댓글 작성 규칙이다.
14
+ module Me2Text
15
+ class << self
16
+ # me2text(`text`)를 HTML로 변환한다.
17
+ #
18
+ # text - 변환할 me2text 형식의 문자열
19
+ # options - 다음과 같은 옵션을 지원한다. :
20
+ # :symbolize - 특정 순서의 문자열을 UNICODE의 해당 심볼로 변환한다.
21
+ # 지정하지 않는 경우 `true`.
22
+ # :open_new_window - +:html+ 형식으로 변환시 link에 대해 클릭하면 새 창으로 열릴
23
+ # 수 있도록 `<a>` 태그에 `target='_blank'`를 삽입한다.
24
+ # 지정하지 않는 경우 `false`.
25
+ # :allow_line_break - 라인브레이크를 허용한다. `:html` 로 변환시 라인브레이크는
26
+ # `<br />` 태그로 변환된다. 지정하지 않는 경우 `false`.
27
+ # :limit - 변환 결과의 글자수를 제한한다. `:limit`에는 숫자를 지정하며 변환 결과는
28
+ # 지정된 글자 수 까지만 변환된다.
29
+ # :link_handler - 문자열에 나타나는 각 링크에 대해 지정된 block이 호출된다.
30
+ def to_html(text, options = {})
31
+ me2text(text, :html, options)
32
+ end
33
+
34
+ # me2text(+text+)를 평문(plain text)로 변환한다.
35
+ #
36
+ # text - 변환할 me2text 형식의 문자열
37
+ # options - 다음과 같은 옵션을 지원한다. :
38
+ # :symbolize - 특정 순서의 문자열을 UNICODE의 해당 심볼로 변환한다.
39
+ # 지정하지 않는 경우 `true`.
40
+ # :allow_line_break - 라인브레이크를 허용한다. `:html` 로 변환시 라인브레이크는
41
+ # `<br />` 태그로 변환된다. 지정하지 않는 경우 `false`.
42
+ # :limit - 변환 결과의 글자수를 제한한다. `:limit`에는 숫자를 지정하며 변환 결과는
43
+ # 지정된 글자 수 까지만 변환된다.
44
+ # :link_handler - 문자열에 나타나는 각 링크에 대해 지정된 block이 호출된다.
45
+ def to_text(text, options = {})
46
+ me2text(text, :text, options)
47
+ end
48
+
49
+ # me2text(`text`)를 지정한 형식(`format`)으로 변환한다.
50
+ #
51
+ # text - 변환할 me2text 형식의 문자열
52
+ # format - 변환 형식을 지정한다. `:html`, `:text` 중 하나를 지정하며
53
+ # 지정하지 않은 경우 +:html+ 이 지정된다. `:html`은 HTML 형식으로 변환하며
54
+ # +:text+는 평문(plain text)으로 변환한다.
55
+ # options - 다음과 같은 옵션을 지원한다. :
56
+ # :symbolize - 특정 순서의 문자열을 UNICODE의 해당 심볼로 변환한다.
57
+ # 지정하지 않는 경우 `true`.
58
+ # :open_new_window - +:html+ 형식으로 변환시 link에 대해 클릭하면 새 창으로 열릴
59
+ # 수 있도록 `<a>` 태그에 `target='_blank'`를 삽입한다.
60
+ # 지정하지 않는 경우 `false`.
61
+ # :allow_line_break - 라인브레이크를 허용한다. `:html` 로 변환시 라인브레이크는
62
+ # `<br />` 태그로 변환된다. 지정하지 않는 경우 `false`.
63
+ # :limit - 변환 결과의 글자수를 제한한다. `:limit`에는 숫자를 지정하며 변환 결과는
64
+ # 지정된 글자 수 까지만 변환된다.
65
+ # :link_handler - 문자열에 나타나는 각 링크에 대해 지정된 block이 호출된다.
66
+ def me2text(text, format = :html, options = {})
67
+ options = {
68
+ :symbolize => true,
69
+ :open_new_window => false,
70
+ :allow_line_break => false,
71
+ :limit => nil,
72
+ :link_handler => nil
73
+ }.merge(options)
74
+ text = strip_linebreak(text) unless options[:allow_line_break]
75
+
76
+ text = Token.join_tokens(Token.tokenize(text), format, options)
77
+
78
+ # 키워드 핸들러 등록시, doublequote 가 결과에 포함되어 있는 경우
79
+ # doublequotize 메소드가 마지막에 호출 됨으로 에러 발생한다.
80
+ text = doublequotize(text) if options[:symbolize]
81
+
82
+ if format == :html
83
+ text = htmlize_linebreak(text) if options[:allow_line_break]
84
+ end
85
+
86
+ strip_control_chars(text)
87
+ end
88
+
89
+ def doublequotize(text) #:nodoc:
90
+ text.gsub(/\"([^"]*)\"/) { |s| "“#{$1}”" }
91
+ end
92
+
93
+ # 라인브레이크를 <br /> 태그로 대체한다.
94
+ def htmlize_linebreak(text)
95
+ text.gsub(/\r\n/, "<br />").gsub(/\n/, "<br />").gsub(/\r/, "<br />")
96
+ end
97
+
98
+ # 컨트롤 문자를 제거한다.
99
+ def strip_control_chars(text)
100
+ text.gsub(/[[:cntrl:]]/, "")
101
+ end
102
+
103
+ # 라인브래이크를 공백으로 변환한다
104
+ def strip_linebreak(text)
105
+ text.gsub(/\s\r\n/, "").gsub(/\r\n/, " ").gsub(/[\r\n]/, " ")
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,26 @@
1
+ require 'me2text'
2
+
3
+ module Me2Text
4
+ module StringExtension
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ base.send(:include, InstanceMethods)
8
+ end
9
+
10
+ module InstanceMethods
11
+ def me2text(format = :html, options = {})
12
+ Me2Text.me2text(self, format, options)
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def me2text(text, format = :html, options = {})
18
+ Me2Text.me2text(text, format, options)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ class String
25
+ include Me2Text::StringExtension
26
+ end
@@ -0,0 +1,345 @@
1
+ # encoding: utf-8
2
+
3
+ module Me2Text
4
+ class Token
5
+ REGEX_ME2LINK = begin
6
+ dquota_s = '\\xe2\\x80\\x9c|\\xe2\\x80\\x9f|\\xe2\\x9d\\x9d|\\xe2\\x80\\xb6|\\xe2\\x80\\x9d|\\x22|\\xef\\xbc\\x82'
7
+ dquota_e = '\\xe2\\x80\\x9d|\\xe2\\x80\\x9e|\\xe2\\x9d\\x9e|\\xcb\\x9d|\\xe2\\x80\\xb3|\\xe2\\x80\\x9e|\\xe2\\x80\\x9f|\\x22|\\xef\\xbc\\x82'
8
+ dquota_ne = '\\xe2\\x80\\x9d\\xe2\\x80\\x9e\\xe2\\x9d\\x9e\\xcb\\x9d\\xe2\\x80\\xb3\\xe2\\x80\\x9e\\xe2\\x80\\x9f\\x22\\xef\\xbc\\x82'
9
+ /(?:#{dquota_s})([^#{dquota_ne}]*)(?:#{dquota_e}):(http[s]?:\/\/[^\s]*)(\s|$)/
10
+ end
11
+ REGEX_URL = /(http[s]?:\/\/[^\s|^\'|^\"]*)([\'|\"|\s]|$)/
12
+ ESCAPE_CHAR = "\xc2\xa0"
13
+
14
+ attr_accessor :text
15
+
16
+ def to_s(format, options = {})
17
+ unless [:html, :text].include?(format)
18
+ raise ArgumentError.new("Unknown format: #{format.inspect}")
19
+ end
20
+ self.send('to_' + format.to_s, options)
21
+ end
22
+
23
+ def to_html(options ={})
24
+ end
25
+
26
+ def to_text(options ={})
27
+ end
28
+
29
+ def length(options ={})
30
+ 1
31
+ end
32
+
33
+ def truncate(nos, format, options = {})
34
+ options = {
35
+ :ellipsis => "…"
36
+ }.merge(options)
37
+
38
+ [options[:ellipsis], 1]
39
+ end
40
+
41
+ protected
42
+
43
+ def htmlize(text, options = {})
44
+ options = {
45
+ :symbolize => true,
46
+ :linklize_class => "write_link"
47
+ }.merge(options)
48
+
49
+ remain = text
50
+ result = ""
51
+ if options[:linklize]
52
+ while (m = remain.match(REGEX_URL))
53
+ url = m[1]
54
+ after_url = m[2]
55
+
56
+ result << htmlize_chars(m.pre_match, options) if !m.pre_match.empty?
57
+ result << "<a href='#{url.to_s.strip}'"
58
+ result << " class='#{options[:linklize_class]}'" if options[:linklize_class]
59
+ result << " target='_blank'" if options[:open_new_window]
60
+ result << ">"
61
+ result << url
62
+ result << "</a>"
63
+ result << after_url
64
+
65
+ remain = m.post_match
66
+ end
67
+ end
68
+ result << htmlize_chars(remain, options)
69
+
70
+ result
71
+ end
72
+
73
+ def htmlize_chars(text, options = {})
74
+ html_result = text.to_s.gsub(/&/, "&amp;").gsub(/</, "&lt;").gsub(/>/, "&gt;")
75
+ html_result = textize(html_result, options)
76
+ html_result
77
+ end
78
+
79
+ def textize(text, options = {})
80
+ options = {
81
+ :symbolize => true
82
+ }.merge(options)
83
+
84
+ if options[:symbolize]
85
+ text = text.gsub(/\.\.\./, "…").
86
+ gsub(/\(TM\)/, "™").
87
+ gsub(/\(R\)/, "®").
88
+ gsub(/\(C\)/, "©").
89
+ gsub(/--/, "—")
90
+ end
91
+ text
92
+ end
93
+
94
+ class << self
95
+ def tokenize(text, options = {})
96
+ tokenize_me2link(text.gsub(/\\\"/, ESCAPE_CHAR), options)
97
+ end
98
+
99
+ def tokenize_me2link(text, options = {})
100
+ tokens = []
101
+ while (m = text.match(REGEX_ME2LINK))
102
+ # 매치 이전 텍스트 처리
103
+ tokens += tokenize_keyword(m.pre_match, options) if !m.pre_match.empty?
104
+
105
+ url = m[2]
106
+ anchor_text = m[1]
107
+ if url
108
+ if !options[:link_handler].nil?
109
+ url = options[:link_handler].call(url, options)
110
+ end
111
+ tokens << Link.new(anchor_text, url, m[3].length > 0)
112
+ else
113
+ tokens += tokenize_keyword(anchor_text, options)
114
+ end
115
+
116
+ text = m.post_match
117
+ end
118
+ if !text.empty?
119
+ tokens += tokenize_keyword(text, options)
120
+ end
121
+
122
+ tokens
123
+ end
124
+
125
+ def tokenize_keyword(text, options = {})
126
+ tokens = []
127
+ while (m = text.match(Keyword::KEYWORD_REGEX))
128
+ tokens += tokenize_plaintext(m.pre_match, options) if !m.pre_match.empty?
129
+ tokens << Keyword.new(m.to_s, options)
130
+ text = m.post_match
131
+ end
132
+ if !text.empty?
133
+ tokens += tokenize_plaintext(text, options)
134
+ end
135
+
136
+ tokens
137
+ end
138
+
139
+ def tokenize_plaintext(text, options = {})
140
+ [Plain.new(text)]
141
+ end
142
+
143
+ def join_tokens(tokens, format, options)
144
+ if options[:limit].nil?
145
+ return tokens.map { |token| token.to_s(format, options) }.join
146
+ end
147
+
148
+ result = ""
149
+ process_length = 0
150
+ tokens.each_with_index do |tk, idx|
151
+ n_len = process_length + tk.length
152
+ r_len = length - n_len
153
+
154
+ # 길이가 남았다.
155
+ if r_len > 0
156
+ process_length = process_length + tk.length
157
+ result << tk.to_s(format, options)
158
+
159
+ # 길이가 딱 맞다.
160
+ elsif r_len == 0
161
+ # 이번 토큰이 마지막 토큰(더이상 추가할 게 없음) 인가?
162
+ if (idx + 1) == tokens.size
163
+ process_length = process_length + tk.length
164
+ result << tk.to_s(format, options)
165
+ else
166
+ # 남은 문자열이 있다.
167
+ val = tk.truncate(0, format, options)
168
+ process_length = process_length + val[1]
169
+ result << val.first
170
+ end
171
+ break
172
+
173
+ # 길이가 r_len만큼 모자르다
174
+ else
175
+ val = tk.truncate(-r_len, format, options)
176
+ process_length = process_length + val[1]
177
+ result << val.first
178
+ break
179
+ end
180
+ end
181
+
182
+ result
183
+ end
184
+ end
185
+ end
186
+
187
+ class Plain < Token
188
+ def initialize(tv)
189
+ @text = tv.gsub(ESCAPE_CHAR, "\"")
190
+ end
191
+
192
+ def to_html(options = {})
193
+ htmlize(@text, options)
194
+ end
195
+
196
+ def to_text(options = {})
197
+ textize(@text, options)
198
+ end
199
+
200
+ def length
201
+ @text.split(//u).length
202
+ end
203
+
204
+ def truncate(nos, format, options = {})
205
+ options = {
206
+ :ellipsis => "…"
207
+ }.merge(options)
208
+
209
+ val = self.to_s(format, options)
210
+ if (val.length - nos) <= 0
211
+ #빼면 아무것도 없다면..
212
+ ##이 링크는 버린다
213
+ options[:ellipsis]
214
+ else
215
+ val = val.split(//u)[0...(val.length - nos) - 1]
216
+ val << options[:ellipsis]
217
+ end
218
+
219
+ @text = val
220
+
221
+ [val, length]
222
+ end
223
+ end
224
+
225
+ class Link < Token
226
+ attr_accessor :link
227
+ attr_accessor :include_ws
228
+
229
+ def initialize(label, link, include_ws = false)
230
+ @text = label.gsub(ESCAPE_CHAR, "\"")
231
+ @link = link.gsub("'","%27").gsub("\"","%22").gsub("<", "%3C").gsub(">", "%3E")
232
+ @include_ws = include_ws
233
+ end
234
+
235
+ def to_label(format,options = {})
236
+ options = options.merge({
237
+ :linklize => false
238
+ })
239
+
240
+ result = if format == :html
241
+ htmlize(@text, options)
242
+ elsif format == :text
243
+ textize(@text, options)
244
+ else
245
+ @text
246
+ end
247
+
248
+ if result.strip.length == 0
249
+ if format == :html
250
+ result = htmlize(" " + link + " ",options)
251
+ elsif format == :text
252
+ result = textize(" " + link + " " ,options)
253
+ else
254
+ @text
255
+ end
256
+ end
257
+
258
+ return result
259
+ end
260
+
261
+ def to_html(options = {})
262
+ if options[:open_new_window]
263
+ "<a href='#{link}' target='_blank'>#{to_label(:html,options)}</a>"
264
+ else
265
+ "<a href='#{link}'>#{to_label(:html,options)}</a>"
266
+ end
267
+ end
268
+
269
+ def to_text(options = {})
270
+ to_label(:text, options)
271
+ end
272
+
273
+ def length(options = {})
274
+ textize(@text,options).length
275
+ end
276
+
277
+ def truncate(nos, format, options = {})
278
+ options = {
279
+ :ellipsis => "…"
280
+ }.merge(options)
281
+
282
+ val = self.to_label(format,options)
283
+ if (val.length - nos) <= 0
284
+ #빼면 아무것도 없다면..
285
+ ##이 링크는 버린다
286
+ options[:ellipsis]
287
+ else
288
+ val = val.split(//u)[0...(val.length-nos) - 1]
289
+ val << options[:ellipsis]
290
+ end
291
+
292
+ @text= val
293
+ [to_s(format,options), length(options)]
294
+ end
295
+ end
296
+
297
+ class Keyword < Token
298
+ KEYWORD_REGEX = /(\[([^\[\]]+)\])/
299
+ attr_accessor :link
300
+
301
+ def initialize(keyword, options)
302
+ # keyword는 "[키워드]" 같은 형태
303
+ _keyword = keyword.to_s.strip.scan(KEYWORD_REGEX)
304
+ _keyword = _keyword.flatten[1]
305
+
306
+ raise "키워드가 없습니다." if _keyword.nil?
307
+
308
+ @text = _keyword.gsub(ESCAPE_CHAR, "\"")
309
+ end
310
+
311
+ def to_html(options = {})
312
+ if options[:keyword_handler] && options[:keyword_handler].is_a?(Proc)
313
+ options[:keyword_handler].call(@text, options)
314
+ else
315
+ "[#{htmlize(@text, options)}]"
316
+ end
317
+ end
318
+
319
+ def to_text(options = {})
320
+ "[#{textize(@text, options)}]"
321
+ end
322
+
323
+ def length(options = {})
324
+ textize(@text, options).length
325
+ end
326
+
327
+ def truncate(nos, format, options = {})
328
+ options = {
329
+ :ellipsis => "…"
330
+ }.merge(options)
331
+
332
+ val = self.to_text(options)
333
+ if (val.length - nos) <= 0
334
+ # 빼면 아무것도 없다면 이 링크는 버린다
335
+ options[:ellipsis]
336
+ else
337
+ val = val.split(//u)[0...(val.length - nos) - 1]
338
+ val << options[:ellipsis]
339
+ end
340
+
341
+ @text = val
342
+ [to_s(format, options), length(options)]
343
+ end
344
+ end
345
+ end
@@ -0,0 +1,3 @@
1
+ module Me2Text
2
+ VERSION = "1.0.0"
3
+ end
data/lib/me2text.rb ADDED
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ major, minor, patch = RUBY_VERSION.split('.')
4
+ if major.to_i == 1 && minor.to_i > 8
5
+ raise("me2text는 ruby 1.9 이상은 현재 지원하지 않습니다.")
6
+ else
7
+ # Ruby 1.8 $KCODE check.
8
+ unless $KCODE[0].chr =~ /u/i
9
+ raise("me2text를 사용하기 위해서는 $KCODE 변수를 'UTF8' 또는 'u'로 지정해야 합니다.")
10
+ end
11
+ end
12
+
13
+ $:.push(File.expand_path("..", __FILE__))
14
+
15
+ module Me2Text
16
+ end
17
+
18
+ require 'me2text/version'
19
+ require 'me2text/me2text'
20
+
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "me2text/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "me2text-ruby"
7
+ s.version = Me2Text::VERSION
8
+ s.authors = ["codian"]
9
+ s.email = ["codian@gmail.com"]
10
+ s.homepage = "http://me2day.net"
11
+ s.summary = %q{me2text parser for ruby}
12
+ s.description = %q{me2text is text format for me2day posting.
13
+ me2text-ruby is ruby library to me2text to HTML or plain text}
14
+ s.rubyforge_project = "me2text-ruby"
15
+ s.files = Dir['{lib/**/*,test/**/*}'] +
16
+ %w(.gitignore me2text-ruby.gemspec Gemfile MIT-LICENSE Rakefile README.md)
17
+ s.test_files = Dir['test/**/*']
18
+ s.executables = ''
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
data/test/test.rb ADDED
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../test_helper', __FILE__)
4
+
5
+ class Me2TextTest < Test::Unit::TestCase
6
+ def test_to_html
7
+ cases = [
8
+ # 일반 텍스트
9
+ ['안녕하세요. 미투데이입니다.', '안녕하세요. 미투데이입니다.'],
10
+ ['"안녕하세요." 미투데이입니다.', '“안녕하세요.” 미투데이입니다.'],
11
+ ['안녕하세요...(C)(R)(TM)-- 미투데이입니다', "안녕하세요…©®™— 미투데이입니다"],
12
+
13
+ # html 이스케이프
14
+ ['안녕하세요. <br /> 미투데이입니다.', '안녕하세요. &lt;br /&gt; 미투데이입니다.'],
15
+ ['안녕하세요. &nbsp;미투데이입니다.', '안녕하세요. &amp;nbsp;미투데이입니다.'],
16
+
17
+ # 링크 문법
18
+ ['"안녕하세요":http://me2day.net . 미투데이입니다.', '<a href=\'http://me2day.net\'>안녕하세요</a>. 미투데이입니다.'],
19
+ ['안녕"하세요":http://me2day.net . 미투데이입니다.', '안녕<a href=\'http://me2day.net\'>하세요</a>. 미투데이입니다.'],
20
+ ['안녕하세요. "미투데이입니다.":http://me2day.net', '안녕하세요. <a href=\'http://me2day.net\'>미투데이입니다.</a>'],
21
+
22
+ # 키워드 문법
23
+ ['[안녕하세요]. 미투데이입니다.', '[안녕하세요]. 미투데이입니다.'],
24
+
25
+ # 따옴표 이스케이프한 경우
26
+ ['"\\"안녕하세요\\"":http://me2day.net . 미투데이입니다.', '<a href=\'http://me2day.net\'>“안녕하세요”</a>. 미투데이입니다.'],
27
+
28
+ # 컨트롤 문자 strip
29
+ ["\000안녕하세요. 미투데이입니다.", '안녕하세요. 미투데이입니다.']
30
+ ]
31
+
32
+ cases.each_with_index do |test, index|
33
+ text = test[0]
34
+ expect = test[1]
35
+ result = Me2Text.me2text(text, :html)
36
+ if expect != result
37
+ flunk "TEXT: #{text}\n" +
38
+ "EXPECT: #{expect}\n" +
39
+ "RESULT: #{result}\n"
40
+ end
41
+ end
42
+ end
43
+
44
+ def test_strip_linebreak
45
+ cases = [
46
+ ["안녕하세요.\n미투데이입니다.", '안녕하세요.<br />미투데이입니다.'],
47
+ ["안녕하세요.\r미투데이입니다.", '안녕하세요.<br />미투데이입니다.'],
48
+ ["안녕하세요.\r\n미투데이입니다.", '안녕하세요.<br />미투데이입니다.'],
49
+ ["안녕하세요.\n\r미투데이입니다.", '안녕하세요.<br /><br />미투데이입니다.'],
50
+ ]
51
+
52
+ cases.each_with_index do |test, index|
53
+ text = test[0]
54
+ expect = test[1]
55
+ result = Me2Text.me2text(text, :html, :allow_line_break => true)
56
+ if expect != result
57
+ flunk "TEXT: #{text.inspect}\n" +
58
+ "EXPECT: #{expect}\n" +
59
+ "RESULT: #{result}\n"
60
+ end
61
+ end
62
+ end
63
+ end
64
+
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ major, minor, patch = RUBY_VERSION.split('.')
4
+ $KCODE = "U" if major.to_i == 1 && minor.to_i < 9
5
+
6
+ require 'test/unit'
7
+ require File.expand_path('../../lib/me2text', __FILE__)
8
+
9
+
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: me2text-ruby
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - codian
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-05-21 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: |-
22
+ me2text is text format for me2day posting.
23
+ me2text-ruby is ruby library to me2text to HTML or plain text
24
+ email:
25
+ - codian@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/me2text/me2text.rb
34
+ - lib/me2text/string_ext.rb
35
+ - lib/me2text/token.rb
36
+ - lib/me2text/version.rb
37
+ - lib/me2text.rb
38
+ - test/test.rb
39
+ - test/test_helper.rb
40
+ - .gitignore
41
+ - me2text-ruby.gemspec
42
+ - Gemfile
43
+ - MIT-LICENSE
44
+ - Rakefile
45
+ - README.md
46
+ homepage: http://me2day.net
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ requirements: []
73
+
74
+ rubyforge_project: me2text-ruby
75
+ rubygems_version: 1.8.23
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: me2text parser for ruby
79
+ test_files:
80
+ - test/test.rb
81
+ - test/test_helper.rb
82
+ has_rdoc: