mail 2.6.6 → 2.7.0.rc1
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 +4 -4
- data/CHANGELOG.rdoc +25 -6
- data/Dependencies.txt +0 -1
- data/Gemfile +5 -8
- data/MIT-LICENSE +1 -1
- data/README.md +22 -11
- data/Rakefile +0 -6
- data/lib/mail.rb +2 -10
- data/lib/mail/attachments_list.rb +3 -2
- data/lib/mail/body.rb +3 -3
- data/lib/mail/core_extensions/smtp.rb +19 -16
- data/lib/mail/core_extensions/string.rb +0 -4
- data/lib/mail/elements/address.rb +9 -4
- data/lib/mail/elements/address_list.rb +10 -18
- data/lib/mail/elements/content_disposition_element.rb +8 -15
- data/lib/mail/elements/content_location_element.rb +5 -10
- data/lib/mail/elements/content_transfer_encoding_element.rb +5 -10
- data/lib/mail/elements/content_type_element.rb +8 -19
- data/lib/mail/elements/date_time_element.rb +6 -14
- data/lib/mail/elements/envelope_from_element.rb +14 -21
- data/lib/mail/elements/message_ids_element.rb +8 -12
- data/lib/mail/elements/mime_version_element.rb +6 -14
- data/lib/mail/elements/phrase_list.rb +6 -9
- data/lib/mail/elements/received_element.rb +9 -15
- data/lib/mail/encodings.rb +12 -14
- data/lib/mail/field.rb +7 -4
- data/lib/mail/fields/common/parameter_hash.rb +1 -1
- data/lib/mail/fields/content_type_field.rb +2 -7
- data/lib/mail/fields/unstructured_field.rb +2 -2
- data/lib/mail/header.rb +1 -0
- data/lib/mail/message.rb +23 -25
- data/lib/mail/multibyte.rb +51 -0
- data/lib/mail/multibyte/chars.rb +27 -27
- data/lib/mail/network/delivery_methods/exim.rb +10 -6
- data/lib/mail/network/delivery_methods/sendmail.rb +2 -6
- data/lib/mail/network/delivery_methods/smtp.rb +14 -6
- data/lib/mail/parsers.rb +16 -24
- data/lib/mail/parsers/address_lists_parser.rb +15321 -112
- data/lib/mail/parsers/address_lists_parser.rl +166 -0
- data/lib/mail/parsers/content_disposition_parser.rb +698 -55
- data/lib/mail/parsers/content_disposition_parser.rl +76 -0
- data/lib/mail/parsers/content_location_parser.rb +565 -23
- data/lib/mail/parsers/content_location_parser.rl +65 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +410 -22
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +58 -0
- data/lib/mail/parsers/content_type_parser.rb +841 -54
- data/lib/mail/parsers/content_type_parser.rl +77 -0
- data/lib/mail/parsers/date_time_parser.rb +773 -26
- data/lib/mail/parsers/date_time_parser.rl +56 -0
- data/lib/mail/parsers/envelope_from_parser.rb +2051 -36
- data/lib/mail/parsers/envelope_from_parser.rl +76 -0
- data/lib/mail/parsers/message_ids_parser.rb +1494 -25
- data/lib/mail/parsers/message_ids_parser.rl +76 -0
- data/lib/mail/parsers/mime_version_parser.rb +393 -26
- data/lib/mail/parsers/mime_version_parser.rl +55 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +529 -19
- data/lib/mail/parsers/phrase_lists_parser.rl +77 -0
- data/lib/mail/parsers/received_parser.rb +4711 -38
- data/lib/mail/parsers/received_parser.rl +78 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +12 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +24 -0
- data/lib/mail/parsers/rfc2045_mime.rl +15 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +14 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +16 -0
- data/lib/mail/parsers/rfc5322.rl +57 -0
- data/lib/mail/parsers/rfc5322_address.rl +70 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +7 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +56 -0
- data/lib/mail/part.rb +1 -1
- data/lib/mail/parts_list.rb +5 -6
- data/lib/mail/utilities.rb +4 -2
- data/lib/mail/version.rb +3 -3
- data/lib/mail/version_specific/ruby_1_8.rb +28 -2
- data/lib/mail/version_specific/ruby_1_9.rb +48 -8
- metadata +28 -45
- data/lib/mail/core_extensions/string/access.rb +0 -146
- data/lib/mail/core_extensions/string/multibyte.rb +0 -79
- data/lib/mail/parsers/ragel.rb +0 -18
- data/lib/mail/parsers/ragel/common.rl +0 -185
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- data/lib/mail/parsers/ragel/ruby.rb +0 -40
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
|
+
require 'net/imap' # for decode_utf7
|
3
4
|
|
4
5
|
module Mail
|
5
6
|
class Ruby18
|
@@ -56,7 +57,27 @@ module Mail
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def Ruby18.transcode_charset(str, from_encoding, to_encoding = 'UTF-8')
|
59
|
-
|
60
|
+
case from_encoding
|
61
|
+
when /utf-?7/i
|
62
|
+
decode_utf7(str)
|
63
|
+
else
|
64
|
+
retried = false
|
65
|
+
begin
|
66
|
+
Iconv.conv("#{normalize_iconv_charset_encoding(to_encoding)}//IGNORE", normalize_iconv_charset_encoding(from_encoding), str)
|
67
|
+
rescue Iconv::InvalidEncoding
|
68
|
+
if retried
|
69
|
+
raise
|
70
|
+
else
|
71
|
+
from_encoding = 'ASCII'
|
72
|
+
retried = true
|
73
|
+
retry
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def Ruby18.decode_utf7(str)
|
80
|
+
Net::IMAP.decode_utf7(str)
|
60
81
|
end
|
61
82
|
|
62
83
|
def Ruby18.b_value_encode(str, encoding)
|
@@ -97,7 +118,12 @@ module Mail
|
|
97
118
|
end
|
98
119
|
|
99
120
|
def Ruby18.param_decode(str, encoding)
|
100
|
-
URI.unescape(str)
|
121
|
+
str = URI.unescape(str)
|
122
|
+
if encoding
|
123
|
+
transcode_charset(str, encoding)
|
124
|
+
else
|
125
|
+
str
|
126
|
+
end
|
101
127
|
end
|
102
128
|
|
103
129
|
def Ruby18.param_encode(str)
|
@@ -5,13 +5,23 @@ module Mail
|
|
5
5
|
class Ruby19
|
6
6
|
class StrictCharsetEncoder
|
7
7
|
def encode(string, charset)
|
8
|
-
|
8
|
+
case charset
|
9
|
+
when /utf-?7/i
|
10
|
+
Mail::Ruby19.decode_utf7(string)
|
11
|
+
else
|
12
|
+
string.force_encoding(Mail::Ruby19.pick_encoding(charset))
|
13
|
+
end
|
9
14
|
end
|
10
15
|
end
|
11
16
|
|
12
17
|
class BestEffortCharsetEncoder
|
13
18
|
def encode(string, charset)
|
14
|
-
|
19
|
+
case charset
|
20
|
+
when /utf-?7/i
|
21
|
+
Mail::Ruby19.decode_utf7(string)
|
22
|
+
else
|
23
|
+
string.force_encoding(pick_encoding(charset))
|
24
|
+
end
|
15
25
|
end
|
16
26
|
|
17
27
|
private
|
@@ -78,7 +88,31 @@ module Mail
|
|
78
88
|
end
|
79
89
|
|
80
90
|
def Ruby19.transcode_charset(str, from_encoding, to_encoding = Encoding::UTF_8)
|
81
|
-
|
91
|
+
to_encoding = Encoding.find(to_encoding)
|
92
|
+
replacement_char = to_encoding == Encoding::UTF_8 ? '�' : '?'
|
93
|
+
charset_encoder.encode(str.dup, from_encoding).encode(to_encoding, :undef => :replace, :invalid => :replace, :replace => replacement_char)
|
94
|
+
end
|
95
|
+
|
96
|
+
# From Ruby stdlib Net::IMAP
|
97
|
+
def Ruby19.encode_utf7(string)
|
98
|
+
string.gsub(/(&)|[^\x20-\x7e]+/) do
|
99
|
+
if $1
|
100
|
+
"&-"
|
101
|
+
else
|
102
|
+
base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0")
|
103
|
+
"&" + base64.delete("=").tr("/", ",") + "-"
|
104
|
+
end
|
105
|
+
end.force_encoding(Encoding::ASCII_8BIT)
|
106
|
+
end
|
107
|
+
|
108
|
+
def Ruby19.decode_utf7(utf7)
|
109
|
+
utf7.gsub(/&([^-]+)?-/n) do
|
110
|
+
if $1
|
111
|
+
($1.tr(",", "/") + "===").unpack("m")[0].encode(Encoding::UTF_8, Encoding::UTF_16BE)
|
112
|
+
else
|
113
|
+
"&"
|
114
|
+
end
|
115
|
+
end
|
82
116
|
end
|
83
117
|
|
84
118
|
def Ruby19.b_value_encode(str, encoding = nil)
|
@@ -93,8 +127,7 @@ module Mail
|
|
93
127
|
str = Ruby19.decode_base64(match[2])
|
94
128
|
str = charset_encoder.encode(str, charset)
|
95
129
|
end
|
96
|
-
|
97
|
-
decoded.valid_encoding? ? decoded : decoded.encode(Encoding::UTF_16LE, :invalid => :replace, :replace => "").encode(Encoding::UTF_8)
|
130
|
+
transcode_to_scrubbed_utf8(str)
|
98
131
|
rescue Encoding::UndefinedConversionError, ArgumentError, Encoding::ConverterNotFoundError
|
99
132
|
warn "Encoding conversion failed #{$!}"
|
100
133
|
str.dup.force_encoding(Encoding::UTF_8)
|
@@ -118,8 +151,7 @@ module Mail
|
|
118
151
|
# jruby/jruby#829 which subtly changes String#encode semantics.
|
119
152
|
str.force_encoding(Encoding::UTF_8) if str.encoding == Encoding::ASCII_8BIT
|
120
153
|
end
|
121
|
-
|
122
|
-
decoded.valid_encoding? ? decoded : decoded.encode(Encoding::UTF_16LE, :invalid => :replace, :replace => "").encode(Encoding::UTF_8)
|
154
|
+
transcode_to_scrubbed_utf8(str)
|
123
155
|
rescue Encoding::UndefinedConversionError, ArgumentError, Encoding::ConverterNotFoundError
|
124
156
|
warn "Encoding conversion failed #{$!}"
|
125
157
|
str.dup.force_encoding(Encoding::UTF_8)
|
@@ -128,7 +160,10 @@ module Mail
|
|
128
160
|
def Ruby19.param_decode(str, encoding)
|
129
161
|
str = uri_parser.unescape(str)
|
130
162
|
str = charset_encoder.encode(str, encoding) if encoding
|
131
|
-
str
|
163
|
+
transcode_to_scrubbed_utf8(str)
|
164
|
+
rescue Encoding::UndefinedConversionError, ArgumentError, Encoding::ConverterNotFoundError
|
165
|
+
warn "Encoding conversion failed #{$!}"
|
166
|
+
str.dup.force_encoding(Encoding::UTF_8)
|
132
167
|
end
|
133
168
|
|
134
169
|
def Ruby19.param_encode(str)
|
@@ -221,6 +256,11 @@ module Mail
|
|
221
256
|
end
|
222
257
|
end
|
223
258
|
end
|
259
|
+
|
260
|
+
def transcode_to_scrubbed_utf8(str)
|
261
|
+
decoded = str.encode(Encoding::UTF_8, :undef => :replace, :invalid => :replace, :replace => "�")
|
262
|
+
decoded.valid_encoding? ? decoded : decoded.encode(Encoding::UTF_16LE, :invalid => :replace, :replace => "�").encode(Encoding::UTF_8)
|
263
|
+
end
|
224
264
|
end
|
225
265
|
end
|
226
266
|
end
|
metadata
CHANGED
@@ -1,35 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikel Lindsaar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: mini_mime
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '4'
|
19
|
+
version: 0.1.1
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '4'
|
26
|
+
version: 0.1.1
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: bundler
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,8 +106,6 @@ files:
|
|
112
106
|
- lib/mail/constants.rb
|
113
107
|
- lib/mail/core_extensions/smtp.rb
|
114
108
|
- lib/mail/core_extensions/string.rb
|
115
|
-
- lib/mail/core_extensions/string/access.rb
|
116
|
-
- lib/mail/core_extensions/string/multibyte.rb
|
117
109
|
- lib/mail/elements.rb
|
118
110
|
- lib/mail/elements/address.rb
|
119
111
|
- lib/mail/elements/address_list.rb
|
@@ -201,45 +193,36 @@ files:
|
|
201
193
|
- lib/mail/network/retriever_methods/test_retriever.rb
|
202
194
|
- lib/mail/parsers.rb
|
203
195
|
- lib/mail/parsers/address_lists_parser.rb
|
196
|
+
- lib/mail/parsers/address_lists_parser.rl
|
204
197
|
- lib/mail/parsers/content_disposition_parser.rb
|
198
|
+
- lib/mail/parsers/content_disposition_parser.rl
|
205
199
|
- lib/mail/parsers/content_location_parser.rb
|
200
|
+
- lib/mail/parsers/content_location_parser.rl
|
206
201
|
- lib/mail/parsers/content_transfer_encoding_parser.rb
|
202
|
+
- lib/mail/parsers/content_transfer_encoding_parser.rl
|
207
203
|
- lib/mail/parsers/content_type_parser.rb
|
204
|
+
- lib/mail/parsers/content_type_parser.rl
|
208
205
|
- lib/mail/parsers/date_time_parser.rb
|
206
|
+
- lib/mail/parsers/date_time_parser.rl
|
209
207
|
- lib/mail/parsers/envelope_from_parser.rb
|
208
|
+
- lib/mail/parsers/envelope_from_parser.rl
|
210
209
|
- lib/mail/parsers/message_ids_parser.rb
|
210
|
+
- lib/mail/parsers/message_ids_parser.rl
|
211
211
|
- lib/mail/parsers/mime_version_parser.rb
|
212
|
+
- lib/mail/parsers/mime_version_parser.rl
|
212
213
|
- lib/mail/parsers/phrase_lists_parser.rb
|
213
|
-
- lib/mail/parsers/
|
214
|
-
- lib/mail/parsers/ragel/common.rl
|
215
|
-
- lib/mail/parsers/ragel/date_time.rl
|
216
|
-
- lib/mail/parsers/ragel/parser_info.rb
|
217
|
-
- lib/mail/parsers/ragel/ruby.rb
|
218
|
-
- lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb
|
219
|
-
- lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl
|
220
|
-
- lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb
|
221
|
-
- lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl
|
222
|
-
- lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb
|
223
|
-
- lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl
|
224
|
-
- lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb
|
225
|
-
- lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl
|
226
|
-
- lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb
|
227
|
-
- lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl
|
228
|
-
- lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb
|
229
|
-
- lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl
|
230
|
-
- lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb
|
231
|
-
- lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl
|
232
|
-
- lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb
|
233
|
-
- lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl
|
234
|
-
- lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb
|
235
|
-
- lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl
|
236
|
-
- lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb
|
237
|
-
- lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl
|
238
|
-
- lib/mail/parsers/ragel/ruby/machines/rb_actions.rl
|
239
|
-
- lib/mail/parsers/ragel/ruby/machines/received_machine.rb
|
240
|
-
- lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl
|
241
|
-
- lib/mail/parsers/ragel/ruby/parser.rb.rl.erb
|
214
|
+
- lib/mail/parsers/phrase_lists_parser.rl
|
242
215
|
- lib/mail/parsers/received_parser.rb
|
216
|
+
- lib/mail/parsers/received_parser.rl
|
217
|
+
- lib/mail/parsers/rfc2045_content_transfer_encoding.rl
|
218
|
+
- lib/mail/parsers/rfc2045_content_type.rl
|
219
|
+
- lib/mail/parsers/rfc2045_mime.rl
|
220
|
+
- lib/mail/parsers/rfc2183_content_disposition.rl
|
221
|
+
- lib/mail/parsers/rfc5234_abnf_core_rules.rl
|
222
|
+
- lib/mail/parsers/rfc5322.rl
|
223
|
+
- lib/mail/parsers/rfc5322_address.rl
|
224
|
+
- lib/mail/parsers/rfc5322_date_time.rl
|
225
|
+
- lib/mail/parsers/rfc5322_lexical_tokens.rl
|
243
226
|
- lib/mail/part.rb
|
244
227
|
- lib/mail/parts_list.rb
|
245
228
|
- lib/mail/utilities.rb
|
@@ -264,12 +247,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
264
247
|
version: '0'
|
265
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
266
249
|
requirements:
|
267
|
-
- - "
|
250
|
+
- - ">"
|
268
251
|
- !ruby/object:Gem::Version
|
269
|
-
version:
|
252
|
+
version: 1.3.1
|
270
253
|
requirements: []
|
271
254
|
rubyforge_project:
|
272
|
-
rubygems_version: 2.6.
|
255
|
+
rubygems_version: 2.6.12
|
273
256
|
signing_key:
|
274
257
|
specification_version: 4
|
275
258
|
summary: Mail provides a nice Ruby DSL for making, sending and reading emails.
|
@@ -1,146 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# This is not loaded if ActiveSupport is already loaded
|
5
|
-
|
6
|
-
# This is an almost cut and paste from ActiveSupport v3.0.6, copied in here so that Mail
|
7
|
-
# itself does not depend on ActiveSupport to avoid versioning conflicts
|
8
|
-
|
9
|
-
class String
|
10
|
-
unless '1.9'.respond_to?(:force_encoding)
|
11
|
-
# Returns the character at the +position+ treating the string as an array (where 0 is the first character).
|
12
|
-
#
|
13
|
-
# Examples:
|
14
|
-
# "hello".at(0) # => "h"
|
15
|
-
# "hello".at(4) # => "o"
|
16
|
-
# "hello".at(10) # => ERROR if < 1.9, nil in 1.9
|
17
|
-
def at(position)
|
18
|
-
mb_chars[position, 1].to_s
|
19
|
-
end
|
20
|
-
|
21
|
-
# Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character).
|
22
|
-
#
|
23
|
-
# Examples:
|
24
|
-
# "hello".from(0) # => "hello"
|
25
|
-
# "hello".from(2) # => "llo"
|
26
|
-
# "hello".from(10) # => "" if < 1.9, nil in 1.9
|
27
|
-
def from(position)
|
28
|
-
mb_chars[position..-1].to_s
|
29
|
-
end
|
30
|
-
|
31
|
-
# Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character).
|
32
|
-
#
|
33
|
-
# Examples:
|
34
|
-
# "hello".to(0) # => "h"
|
35
|
-
# "hello".to(2) # => "hel"
|
36
|
-
# "hello".to(10) # => "hello"
|
37
|
-
def to(position)
|
38
|
-
mb_chars[0..position].to_s
|
39
|
-
end
|
40
|
-
|
41
|
-
# Returns the first character of the string or the first +limit+ characters.
|
42
|
-
#
|
43
|
-
# Examples:
|
44
|
-
# "hello".first # => "h"
|
45
|
-
# "hello".first(2) # => "he"
|
46
|
-
# "hello".first(10) # => "hello"
|
47
|
-
def first(limit = 1)
|
48
|
-
if limit == 0
|
49
|
-
''
|
50
|
-
elsif limit >= size
|
51
|
-
self
|
52
|
-
else
|
53
|
-
mb_chars[0...limit].to_s
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# Returns the last character of the string or the last +limit+ characters.
|
58
|
-
#
|
59
|
-
# Examples:
|
60
|
-
# "hello".last # => "o"
|
61
|
-
# "hello".last(2) # => "lo"
|
62
|
-
# "hello".last(10) # => "hello"
|
63
|
-
def last(limit = 1)
|
64
|
-
if limit == 0
|
65
|
-
''
|
66
|
-
elsif limit >= size
|
67
|
-
self
|
68
|
-
else
|
69
|
-
mb_chars[(-limit)..-1].to_s
|
70
|
-
end
|
71
|
-
end
|
72
|
-
else
|
73
|
-
def at(position)
|
74
|
-
self[position]
|
75
|
-
end
|
76
|
-
|
77
|
-
def from(position)
|
78
|
-
self[position..-1]
|
79
|
-
end
|
80
|
-
|
81
|
-
def to(position)
|
82
|
-
self[0..position]
|
83
|
-
end
|
84
|
-
|
85
|
-
def first(limit = 1)
|
86
|
-
if limit == 0
|
87
|
-
''
|
88
|
-
elsif limit >= size
|
89
|
-
self
|
90
|
-
else
|
91
|
-
to(limit - 1)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def last(limit = 1)
|
96
|
-
if limit == 0
|
97
|
-
''
|
98
|
-
elsif limit >= size
|
99
|
-
self
|
100
|
-
else
|
101
|
-
from(-limit)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
if Module.method(:const_get).arity == 1
|
107
|
-
# Tries to find a constant with the name specified in the argument string:
|
108
|
-
#
|
109
|
-
# "Module".constantize # => Module
|
110
|
-
# "Test::Unit".constantize # => Test::Unit
|
111
|
-
#
|
112
|
-
# The name is assumed to be the one of a top-level constant, no matter whether
|
113
|
-
# it starts with "::" or not. No lexical context is taken into account:
|
114
|
-
#
|
115
|
-
# C = 'outside'
|
116
|
-
# module M
|
117
|
-
# C = 'inside'
|
118
|
-
# C # => 'inside'
|
119
|
-
# "C".constantize # => 'outside', same as ::C
|
120
|
-
# end
|
121
|
-
#
|
122
|
-
# NameError is raised when the name is not in CamelCase or the constant is
|
123
|
-
# unknown.
|
124
|
-
def constantize
|
125
|
-
names = self.split('::')
|
126
|
-
names.shift if names.empty? || names.first.empty?
|
127
|
-
|
128
|
-
constant = Object
|
129
|
-
names.each do |name|
|
130
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
131
|
-
end
|
132
|
-
constant
|
133
|
-
end
|
134
|
-
else
|
135
|
-
def constantize #:nodoc:
|
136
|
-
names = self.split('::')
|
137
|
-
names.shift if names.empty? || names.first.empty?
|
138
|
-
|
139
|
-
constant = Object
|
140
|
-
names.each do |name|
|
141
|
-
constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
|
142
|
-
end
|
143
|
-
constant
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# This is not loaded if ActiveSupport is already loaded
|
5
|
-
|
6
|
-
# This is an almost cut and paste from ActiveSupport v3.0.6, copied in here so that Mail
|
7
|
-
# itself does not depend on ActiveSupport to avoid versioning conflicts
|
8
|
-
|
9
|
-
require 'mail/multibyte'
|
10
|
-
|
11
|
-
class String
|
12
|
-
if RUBY_VERSION >= "1.9"
|
13
|
-
# == Multibyte proxy
|
14
|
-
#
|
15
|
-
# +mb_chars+ is a multibyte safe proxy for string methods.
|
16
|
-
#
|
17
|
-
# In Ruby 1.8 and older it creates and returns an instance of the Mail::Multibyte::Chars class which
|
18
|
-
# encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
|
19
|
-
# class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsuled string.
|
20
|
-
#
|
21
|
-
# name = 'Claus Müller'
|
22
|
-
# name.reverse # => "rell??M sualC"
|
23
|
-
# name.length # => 13
|
24
|
-
#
|
25
|
-
# name.mb_chars.reverse.to_s # => "rellüM sualC"
|
26
|
-
# name.mb_chars.length # => 12
|
27
|
-
#
|
28
|
-
# In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that
|
29
|
-
# it becomes easy to run one version of your code on multiple Ruby versions.
|
30
|
-
#
|
31
|
-
# == Method chaining
|
32
|
-
#
|
33
|
-
# All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
|
34
|
-
# method chaining on the result of any of these methods.
|
35
|
-
#
|
36
|
-
# name.mb_chars.reverse.length # => 12
|
37
|
-
#
|
38
|
-
# == Interoperability and configuration
|
39
|
-
#
|
40
|
-
# The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
|
41
|
-
# String and Char work like expected. The bang! methods change the internal string representation in the Chars
|
42
|
-
# object. Interoperability problems can be resolved easily with a +to_s+ call.
|
43
|
-
#
|
44
|
-
# For more information about the methods defined on the Chars proxy see Mail::Multibyte::Chars. For
|
45
|
-
# information about how to change the default Multibyte behaviour see Mail::Multibyte.
|
46
|
-
def mb_chars
|
47
|
-
if Mail::Multibyte.proxy_class.consumes?(self)
|
48
|
-
Mail::Multibyte.proxy_class.new(self)
|
49
|
-
else
|
50
|
-
self
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def is_utf8? #:nodoc
|
55
|
-
case encoding
|
56
|
-
when Encoding::UTF_8
|
57
|
-
valid_encoding?
|
58
|
-
when Encoding::ASCII_8BIT, Encoding::US_ASCII
|
59
|
-
dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
60
|
-
else
|
61
|
-
false
|
62
|
-
end
|
63
|
-
end
|
64
|
-
else
|
65
|
-
def mb_chars
|
66
|
-
if Mail::Multibyte.proxy_class.wants?(self)
|
67
|
-
Mail::Multibyte.proxy_class.new(self)
|
68
|
-
else
|
69
|
-
self
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have
|
74
|
-
# them), returns false otherwise.
|
75
|
-
def is_utf8?
|
76
|
-
Mail::Multibyte::Chars.consumes?(self)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|