email_reply_parser 0.5.9 → 0.5.10

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
- SHA1:
3
- metadata.gz: 18ed91d7b72ad0b331359d9719a6f69f02366bdd
4
- data.tar.gz: b97b2b17d548dfc86066001d936b49bf6035a0e1
2
+ SHA256:
3
+ metadata.gz: 1d5b9fdfe30fe4feec4e1b84c68b25180b5da4cbe6aa8cebae7d7b725c6918c6
4
+ data.tar.gz: e046ee4ce446ee8a54d2e669ae1cd10bc0ae7e5f9e55c28d439991f7c8311965
5
5
  SHA512:
6
- metadata.gz: fb73afe46d2313905f2cf542d5adf134439bed105922272f53bc6a1e93a3a786e2ab18445dcb0f6712c62251ef0a0632c8cdf1dca441b0d6b6413cd6b83cc8ba
7
- data.tar.gz: 74370b59c92a813864096e4436c8c606bdc350d1ad43af12eded545d4eea38ea76764a98c5bbb3864ef813694f51eefb3895c3622cdd78844ebfff2354be32bf
6
+ metadata.gz: 1e4680771a08970cf019ad1bbeb7a2de56b34df351cca6a6a10aaeebff681eff71e4e2fce7809667ab9e5d1505506d5835d8e180dae731825c97a1ef3ae30cf8
7
+ data.tar.gz: cef0b121c8c201116348fa880274191b1020ed189c11b0c49a8f13e5d00b619a40aeac8eafe1fb09e908e9ff179d3b47692212364192fe3d7adde33a2c6cfc5f
data/README.md CHANGED
@@ -11,7 +11,7 @@ See the [Ruby docs][rubydocs] for more information.
11
11
 
12
12
  [rubydocs]: http://rubydoc.info/gems/email_reply_parser/
13
13
 
14
- ##Usage
14
+ ## Usage
15
15
 
16
16
  To parse reply body:
17
17
 
@@ -1,60 +1,33 @@
1
1
  $LOAD_PATH.unshift '.'
2
2
  require 'lib/email_reply_parser'
3
3
 
4
- ## This is the rakegem gemspec template. Make sure you read and understand
5
- ## all of the comments. Some sections require modification, and others can
6
- ## be deleted if you don't need them. Once you understand the contents of
7
- ## this file, feel free to delete any comments that begin with two hash marks.
8
- ## You can find comprehensive Gem::Specification documentation, at
9
- ## http://docs.rubygems.org/read/chapter/20
10
4
  Gem::Specification.new do |s|
11
5
  s.specification_version = 2 if s.respond_to? :specification_version=
12
6
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
13
7
  s.rubygems_version = '1.3.5'
8
+ s.license = 'MIT'
14
9
 
15
- ## Leave these as is they will be modified for you by the rake gemspec task.
16
- ## If your rubyforge_project name is different, then edit it and comment out
17
- ## the sub! line in the Rakefile
18
10
  s.name = 'email_reply_parser'
19
11
  s.version = EmailReplyParser::VERSION
20
12
  s.date = Time.now.strftime('%Y-%m-%d')
21
- s.rubyforge_project = 'email_reply_parser'
22
13
 
23
- ## Make sure your summary is short. The description may be as long
24
- ## as you like.
25
- s.summary = "Short description used in Gem listings."
26
- s.description = "Long description. Maybe copied from the README."
14
+ s.summary = "EmailReplyParser is a small library to parse plain text " \
15
+ "email content."
16
+ s.description = "EmailReplyParser is a small library to parse plain text " \
17
+ "email content. This is what GitHub uses to display comments " \
18
+ "that were created from email replies."
27
19
 
28
- ## List the primary authors. If there are a bunch of authors, it's probably
29
- ## better to set the email to an email list or something. If you don't have
30
- ## a custom homepage, consider using your GitHub URL or the like.
31
20
  s.authors = ["Rick Olson"]
32
21
  s.email = 'technoweenie@gmail.com'
33
22
  s.homepage = 'http://github.com/github/email_reply_parser'
34
23
 
35
- ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
36
- ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
37
24
  s.require_paths = %w[lib]
38
25
 
39
- ## This sections is only necessary if you have C extensions.
40
- #s.require_paths << 'ext'
41
- #s.extensions = %w[ext/extconf.rb]
42
-
43
- ## If your gem includes any executables, list them here.
44
- #s.executables = ["name"]
45
- #s.default_executable = 'name'
46
-
47
- ## Specify any RDoc options here. You'll want to add your README and
48
- ## LICENSE files to the extra_rdoc_files list.
49
26
  s.rdoc_options = ["--charset=UTF-8"]
50
27
  s.extra_rdoc_files = %w[README.md LICENSE]
51
28
 
52
- ## List your runtime dependencies here. Runtime dependencies are those
53
- ## that are needed for an end user to actually USE your code.
54
29
  #s.add_dependency('DEPNAME', [">= 1.1.0", "< 2.0.0"])
55
30
 
56
- ## List your development dependencies here. Development dependencies are
57
- ## those that are only needed during development
58
31
  #s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
59
32
 
60
33
  ## Leave this section as-is. It will be automatically generated from the
@@ -93,8 +66,5 @@ Gem::Specification.new do |s|
93
66
  ]
94
67
  # = MANIFEST =
95
68
 
96
- ## Test files will be grabbed from the file list. Make sure the path glob
97
- ## matches what you actually use.
98
69
  s.test_files = s.files.select { |path| path =~ /^test\/.*_test\.rb/ }
99
70
  end
100
-
@@ -30,7 +30,7 @@ require 'strscan'
30
30
  #
31
31
  # [mail]: https://github.com/mikel/mail
32
32
  class EmailReplyParser
33
- VERSION = "0.5.9"
33
+ VERSION = "0.5.10"
34
34
 
35
35
  # Public: Splits an email body into a list of Fragments.
36
36
  #
@@ -132,14 +132,8 @@ class EmailReplyParser
132
132
 
133
133
  private
134
134
  EMPTY = "".freeze
135
- SIGNATURE = '(?m)(--\s*$|__\s*$|\w-$)|(^(\w+\s*){1,3} ym morf tneS$)'
136
-
137
- begin
138
- require 're2'
139
- SIG_REGEX = RE2::Regexp.new(SIGNATURE)
140
- rescue LoadError
141
- SIG_REGEX = Regexp.new(SIGNATURE)
142
- end
135
+ SIGNATURE = '(?m)(--\s*$|__\s*$|\w-$)|(^(\w+\s+){1,3}ym morf tneS$)'
136
+ SIG_REGEX = Regexp.new(SIGNATURE)
143
137
 
144
138
  ### Line-by-Line Parsing
145
139
 
@@ -188,7 +182,7 @@ class EmailReplyParser
188
182
  #
189
183
  # Returns true if the line is a valid header, or false.
190
184
  def quote_header?(line)
191
- line =~ /^:etorw.*nO$/
185
+ line =~ /^:etorw.*nO$/ || line =~ /^.*:(morF|tneS|oT|tcejbuS)$/
192
186
  end
193
187
 
194
188
  # Builds the fragment string and reverses it, after all lines have been
@@ -50,10 +50,10 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
50
50
  assert_equal [false, true, false, false, true],
51
51
  reply.fragments.map { |f| f.signature? }
52
52
 
53
- assert_match /^Oh thanks.\n\nHaving/, reply.fragments[0].to_s
54
- assert_match /^-A/, reply.fragments[1].to_s
55
- assert_match /^On [^\:]+\:/, reply.fragments[2].to_s
56
- assert_match /^_/, reply.fragments[4].to_s
53
+ assert_match(/^Oh thanks.\n\nHaving/, reply.fragments[0].to_s)
54
+ assert_match(/^-A/, reply.fragments[1].to_s)
55
+ assert_match(/^On [^\:]+\:/, reply.fragments[2].to_s)
56
+ assert_match(/^_/, reply.fragments[4].to_s)
57
57
  end
58
58
 
59
59
  def test_reads_bottom_post
@@ -68,10 +68,10 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
68
68
  reply.fragments.map { |f| f.hidden? }
69
69
 
70
70
  assert_equal "Hi,", reply.fragments[0].to_s
71
- assert_match /^On [^\:]+\:/, reply.fragments[1].to_s
72
- assert_match /^You can list/, reply.fragments[2].to_s
73
- assert_match /^> /, reply.fragments[3].to_s
74
- assert_match /^_/, reply.fragments[5].to_s
71
+ assert_match(/^On [^\:]+\:/, reply.fragments[1].to_s)
72
+ assert_match(/^You can list/, reply.fragments[2].to_s)
73
+ assert_match(/^> /, reply.fragments[3].to_s)
74
+ assert_match(/^_/, reply.fragments[5].to_s)
75
75
  end
76
76
 
77
77
  def test_reads_inline_replies
@@ -85,11 +85,11 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
85
85
  assert_equal [false, false, false, false, true, true, true],
86
86
  reply.fragments.map { |f| f.hidden? }
87
87
 
88
- assert_match /^On [^\:]+\:/, reply.fragments[0].to_s
89
- assert_match /^I will reply/, reply.fragments[1].to_s
88
+ assert_match(/^On [^\:]+\:/, reply.fragments[0].to_s)
89
+ assert_match(/^I will reply/, reply.fragments[1].to_s)
90
90
  assert_match "okay?", reply.fragments[2].to_s
91
- assert_match /^and under this./, reply.fragments[3].to_s
92
- assert_match /inline/, reply.fragments[4].to_s
91
+ assert_match(/^and under this./, reply.fragments[3].to_s)
92
+ assert_match(/inline/, reply.fragments[4].to_s)
93
93
  assert_equal "\n", reply.fragments[5].to_s
94
94
  assert_equal "--\nHey there, this is my signature\n", reply.fragments[6].to_s
95
95
  end
@@ -97,9 +97,9 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
97
97
  def test_recognizes_date_string_above_quote
98
98
  reply = email :email_1_4
99
99
 
100
- assert_match /^Awesome/, reply.fragments[0].to_s
101
- assert_match /^On/, reply.fragments[1].to_s
102
- assert_match /Loader/, reply.fragments[1].to_s
100
+ assert_match(/^Awesome/, reply.fragments[0].to_s)
101
+ assert_match(/^On/, reply.fragments[1].to_s)
102
+ assert_match(/Loader/, reply.fragments[1].to_s)
103
103
  end
104
104
 
105
105
  def test_a_complex_body_with_only_one_fragment
@@ -115,23 +115,28 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
115
115
  assert_equal [false, false], reply.fragments.map { |f| f.quoted? }
116
116
  assert_equal [false, true], reply.fragments.map { |f| f.signature? }
117
117
  assert_equal [false, true], reply.fragments.map { |f| f.hidden? }
118
- assert_match /^-- \nrick/, reply.fragments[1].to_s
118
+ assert_match(/^-- \nrick/, reply.fragments[1].to_s)
119
119
  end
120
120
 
121
121
  def test_deals_with_multiline_reply_headers
122
122
  reply = email :email_1_6
123
123
 
124
- assert_match /^I get/, reply.fragments[0].to_s
125
- assert_match /^On/, reply.fragments[1].to_s
126
- assert_match /Was this/, reply.fragments[1].to_s
124
+ assert_match(/^I get/, reply.fragments[0].to_s)
125
+ assert_match(/^On/, reply.fragments[1].to_s)
126
+ assert_match(/Was this/, reply.fragments[1].to_s)
127
127
  end
128
128
 
129
129
  def test_deals_with_windows_line_endings
130
130
  reply = email :email_1_7
131
131
 
132
- assert_match /:\+1:/, reply.fragments[0].to_s
133
- assert_match /^On/, reply.fragments[1].to_s
134
- assert_match /Steps 0-2/, reply.fragments[1].to_s
132
+ assert_match(/:\+1:/, reply.fragments[0].to_s)
133
+ assert_match(/^On/, reply.fragments[1].to_s)
134
+ assert_match(/Steps 0-2/, reply.fragments[1].to_s)
135
+ end
136
+
137
+ def test_handles_non_ascii_characters
138
+ non_ascii_body = "Here’s a test."
139
+ assert_equal non_ascii_body, EmailReplyParser.parse_reply(non_ascii_body)
135
140
  end
136
141
 
137
142
  def test_does_not_modify_input_string
@@ -155,6 +160,11 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
155
160
  assert_equal "Outlook with a reply directly above line", EmailReplyParser.parse_reply(body)
156
161
  end
157
162
 
163
+ def test_parse_out_just_top_for_outlook_with_no_line
164
+ body = IO.read EMAIL_FIXTURE_PATH.join("email_2_3.txt").to_s
165
+ assert_equal "Outlook with a reply directly above line", EmailReplyParser.parse_reply(body)
166
+ end
167
+
158
168
  def test_parse_out_sent_from_iPhone
159
169
  body = IO.read EMAIL_FIXTURE_PATH.join("email_iPhone.txt").to_s
160
170
  assert_equal "Here is another email", EmailReplyParser.parse_reply(body)
@@ -188,14 +198,14 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
188
198
 
189
199
  def test_one_is_not_on
190
200
  reply = email("email_one_is_not_on")
191
- assert_match /One outstanding question/, reply.fragments[0].to_s
192
- assert_match /^On Oct 1, 2012/, reply.fragments[1].to_s
201
+ assert_match(/One outstanding question/, reply.fragments[0].to_s)
202
+ assert_match(/^On Oct 1, 2012/, reply.fragments[1].to_s)
193
203
  end
194
204
 
195
205
  def test_mulitple_on
196
206
  reply = email("greedy_on")
197
- assert_match /^On your remote host/, reply.fragments[0].to_s
198
- assert_match /^On 9 Jan 2014/, reply.fragments[1].to_s
207
+ assert_match(/^On your remote host/, reply.fragments[0].to_s)
208
+ assert_match(/^On 9 Jan 2014/, reply.fragments[1].to_s)
199
209
  assert_equal [false, true, false], reply.fragments.map { |f| f.quoted? }
200
210
  assert_equal [false, false, false], reply.fragments.map { |f| f.signature? }
201
211
  assert_equal [false, true, true], reply.fragments.map { |f| f.hidden? }
@@ -203,8 +213,8 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
203
213
 
204
214
  def test_pathological_emails
205
215
  t0 = Time.now
206
- reply = email("pathological")
207
- assert (Time.now - t0) < 1, "Took too long, upgrade to re2 gem."
216
+ email("pathological")
217
+ assert (Time.now - t0) < 1, "Took too long, upgrade to re2 gem. See https://rubygems.org/gems/re2"
208
218
  end
209
219
 
210
220
  def test_doesnt_remove_signature_delimiter_in_mid_line
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: email_reply_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rick Olson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-21 00:00:00.000000000 Z
11
+ date: 2019-08-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Long description. Maybe copied from the README.
13
+ description: EmailReplyParser is a small library to parse plain text email content.
14
+ This is what GitHub uses to display comments that were created from email replies.
14
15
  email: technoweenie@gmail.com
15
16
  executables: []
16
17
  extensions: []
@@ -47,7 +48,8 @@ files:
47
48
  - test/emails/greedy_on.txt
48
49
  - test/emails/pathological.txt
49
50
  homepage: http://github.com/github/email_reply_parser
50
- licenses: []
51
+ licenses:
52
+ - MIT
51
53
  metadata: {}
52
54
  post_install_message:
53
55
  rdoc_options:
@@ -65,11 +67,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
67
  - !ruby/object:Gem::Version
66
68
  version: '0'
67
69
  requirements: []
68
- rubyforge_project: email_reply_parser
69
- rubygems_version: 2.6.6
70
+ rubygems_version: 3.0.1
70
71
  signing_key:
71
72
  specification_version: 2
72
- summary: Short description used in Gem listings.
73
+ summary: EmailReplyParser is a small library to parse plain text email content.
73
74
  test_files:
74
75
  - test/email_reply_parser_test.rb
75
- has_rdoc: