email_reply_trimmer 0.1.13 → 0.3.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/README.md +4 -4
  4. data/Rakefile +1 -7
  5. data/email_reply_trimmer.gemspec +5 -3
  6. data/lib/email_reply_trimmer/delimiter_matcher.rb +3 -2
  7. data/lib/email_reply_trimmer/email_header_matcher.rb +6 -5
  8. data/lib/email_reply_trimmer/embedded_email_matcher.rb +4 -3
  9. data/lib/email_reply_trimmer/empty_line_matcher.rb +1 -0
  10. data/lib/email_reply_trimmer/quote_matcher.rb +1 -0
  11. data/lib/email_reply_trimmer/signature_matcher.rb +2 -1
  12. data/lib/email_reply_trimmer.rb +33 -7
  13. data/test/elided/block_code_spacers.txt +0 -0
  14. data/test/elided/complete_german_quote_at_end.txt +3 -0
  15. data/test/elided/delimiter_before_forwarded_message.txt +6 -0
  16. data/test/elided/delimiter_inside_new_reply.txt +2 -0
  17. data/test/elided/inline_images_before_reply_text.txt +2 -0
  18. data/test/elided/reply_after_selected_german_quote.txt +1 -0
  19. data/test/elided/separate_inline_images_before_reply_text.txt +2 -0
  20. data/test/emails/block_code_spacers.txt +13 -0
  21. data/test/emails/complete_german_quote_at_end.txt +10 -0
  22. data/test/emails/delimiter_before_forwarded_message.txt +8 -0
  23. data/test/emails/delimiter_inside_new_reply.txt +13 -0
  24. data/test/emails/inline_images_before_reply_text.txt +15 -0
  25. data/test/emails/reply_after_selected_german_quote.txt +9 -0
  26. data/test/emails/separate_inline_images_before_reply_text.txt +12 -0
  27. data/test/test_email_matcher.rb +1 -0
  28. data/test/test_email_reply_trimmer.rb +2 -0
  29. data/test/trimmed/block_code_spacers.txt +13 -0
  30. data/test/trimmed/complete_german_quote_at_end.txt +6 -0
  31. data/test/trimmed/delimiter_before_forwarded_message.txt +1 -0
  32. data/test/trimmed/delimiter_inside_new_reply.txt +10 -0
  33. data/test/trimmed/inline_images_before_reply_text.txt +12 -0
  34. data/test/trimmed/reply_after_selected_german_quote.txt +8 -0
  35. data/test/trimmed/separate_inline_images_before_reply_text.txt +9 -0
  36. metadata +45 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c094ba472eabd06ed02276c4ec9e42cb32ccb873871e46e55c46cd4640425470
4
- data.tar.gz: 968cee2c9b3de46ef86814dd84ee8449c400e9c5fa8d61363cbb90064204fadf
3
+ metadata.gz: 599c45c00b2a4848c83f6290b8690b81fdbfc44a6bf878ca268cfa7bc7375712
4
+ data.tar.gz: c5197cdf9e8243e817456a02ae2e9e6884e80e76329a47f471b7881473ebf37b
5
5
  SHA512:
6
- metadata.gz: 6c71cad161a2aaa27e813ff63f91b1e10359d73ffc95d0d01df0374dc8cc9a2ba506985cd4e33d12e63b3f41cd9e6f66bbe42293feea3f6e968c7d90e79a88de
7
- data.tar.gz: e7e3661094d8b1183f572b7e847cac62a71215a341d12b627e0b2d5cfedfdad161f858b8aba3d97463d5ffda5919211da2b268dbd75e7edc48a95811d1e5b481
6
+ metadata.gz: b4f5ff546a1952cc8aa545f228f3312194f5220ff26599c9a75e43c39742851b7055a401d0e89cc0d1398781f833723cd6022815f4fa19ede430944aaa37a6b2
7
+ data.tar.gz: d63d04e31018467ce73fc6254bd325e66241ede1c0c0d12ac2b33db5ad268315b06dfcacf31ee9f57fc4ed5bca5c0290713a068c28525d69aa919c6cfbe8111e
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  # Specify your gem's dependencies in email_reply_trimmer.gemspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Discourse Email Reply Trimmer [![Build Status](https://api.travis-ci.org/discourse/email_reply_trimmer.svg?branch=master)](https://travis-ci.org/discourse/email_reply_trimmer)
1
+ # Discourse Email Reply Trimmer
2
2
 
3
3
  EmailReplyTrimmer is a small library to trim replies from plain text email.
4
4
 
@@ -16,6 +16,6 @@ Run `rake` to run the tests.
16
16
 
17
17
  ## Inspirations
18
18
 
19
- - [GitHub's Email Reply Parser](https://github.com/github/email_reply_parser)
20
- - [MailGun's Talon](https://github.com/mailgun/talon)
21
- - [Vitor R. Carvalho's Learning to Extract Signature and Reply Lines from Email](http://www.cs.cmu.edu/~vitor/papers/sigFilePaper_finalversion.pdf)
19
+ - [GitHub's Email Reply Parser](https://github.com/github/email_reply_parser)
20
+ - [MailGun's Talon](https://github.com/mailgun/talon)
21
+ - [Vitor R. Carvalho's Learning to Extract Signature and Reply Lines from Email](http://www.cs.cmu.edu/~vitor/papers/sigFilePaper_finalversion.pdf)
data/Rakefile CHANGED
@@ -1,10 +1,4 @@
1
- def name
2
- @name ||= Dir["*.gemspec"].first.split(".").first
3
- end
4
-
5
- def version
6
- @version ||= File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*['"](?'version'\d+\.\d+\.\d+)['"]/, "version"]
7
- end
1
+ # frozen_string_literal: true
8
2
 
9
3
  task default: :test
10
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative "lib/email_reply_trimmer"
2
3
 
3
4
  Gem::Specification.new do |s|
@@ -9,7 +10,7 @@ Gem::Specification.new do |s|
9
10
  s.description = "EmailReplyTrimmer is a small library to trim replies from plain text email."
10
11
 
11
12
  s.authors = ["Régis Hanol"]
12
- s.email = ["regis+rubygems@hanol.fr"]
13
+ s.email = ["rubygems@hanol.fr"]
13
14
 
14
15
  s.homepage = "https://github.com/discourse/email_reply_trimmer"
15
16
  s.license = "MIT"
@@ -18,7 +19,8 @@ Gem::Specification.new do |s|
18
19
  s.files = Dir["**/*"].reject { |path| File.directory?(path) || path =~ /.*\.gem$/ }
19
20
  s.test_files = s.files.select { |path| path =~ /^test\/.+_test\.rb$/ }
20
21
 
21
- s.add_development_dependency 'rake', '~> 12'
22
+ s.add_development_dependency 'rake', '~> 13'
22
23
  s.add_development_dependency 'minitest', '~> 5'
23
- s.add_development_dependency 'rubocop', '~> 0.52.1'
24
+ s.add_development_dependency 'rubocop'
25
+ s.add_development_dependency 'rubocop-discourse'
24
26
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  class DelimiterMatcher
2
3
 
3
- DELIMITER_CHARACTERS ||= "-_,=+~#*ᐧ—"
4
- DELIMITER_REGEX ||= /^[[:blank:]]*[#{Regexp.escape(DELIMITER_CHARACTERS)}]+[[:blank:]]*$/
4
+ DELIMITER_CHARACTERS = "-_,=+~#*ᐧ—"
5
+ DELIMITER_REGEX = /^[[:blank:]]*[#{Regexp.escape(DELIMITER_CHARACTERS)}]+[[:blank:]]*$/
5
6
 
6
7
  def self.match?(line)
7
8
  line =~ DELIMITER_REGEX
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  class EmailHeaderMatcher
2
3
 
3
- EMAIL_HEADERS_WITH_DATE_MARKERS ||= [
4
+ EMAIL_HEADERS_WITH_DATE_MARKERS = [
4
5
  # Norwegian
5
6
  ["Sendt"],
6
7
  # English
@@ -25,11 +26,11 @@ class EmailHeaderMatcher
25
26
  ["发送时间"],
26
27
  ]
27
28
 
28
- EMAIL_HEADERS_WITH_DATE_REGEXES ||= EMAIL_HEADERS_WITH_DATE_MARKERS.map do |header|
29
+ EMAIL_HEADERS_WITH_DATE_REGEXES = EMAIL_HEADERS_WITH_DATE_MARKERS.map do |header|
29
30
  /^[[:blank:]*]*(?:#{header.join("|")})[[:blank:]*]*:.*\d+/
30
31
  end
31
32
 
32
- EMAIL_HEADERS_WITH_TEXT_MARKERS ||= [
33
+ EMAIL_HEADERS_WITH_TEXT_MARKERS = [
33
34
  # Norwegian
34
35
  ["Fra", "Til", "Emne"],
35
36
  # English
@@ -52,11 +53,11 @@ class EmailHeaderMatcher
52
53
  ["发件人", "收件人", "主题"],
53
54
  ]
54
55
 
55
- EMAIL_HEADERS_WITH_TEXT_REGEXES ||= EMAIL_HEADERS_WITH_TEXT_MARKERS.map do |header|
56
+ EMAIL_HEADERS_WITH_TEXT_REGEXES = EMAIL_HEADERS_WITH_TEXT_MARKERS.map do |header|
56
57
  /^[[:blank:]*]*(?:#{header.join("|")})[[:blank:]*]*:.*[[:word:]]+/i
57
58
  end
58
59
 
59
- EMAIL_HEADER_REGEXES ||= [
60
+ EMAIL_HEADER_REGEXES = [
60
61
  EMAIL_HEADERS_WITH_DATE_REGEXES,
61
62
  EMAIL_HEADERS_WITH_TEXT_REGEXES,
62
63
  ].flatten
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class EmbeddedEmailMatcher
2
3
 
3
4
  # On Wed, Sep 25, 2013, at 03:57 PM, jorge_castro wrote:
@@ -11,7 +12,7 @@ class EmbeddedEmailMatcher
11
12
  # Em seg, 27 de jul de 2015 17:13, Neil Lalonde <info@discourse.org> escreveu:
12
13
  # El jueves, 21 de noviembre de 2013, codinghorror escribió:
13
14
  # At 6/16/2016 08:32 PM, you wrote:
14
- ON_DATE_SOMEONE_WROTE_REGEXES ||= [
15
+ ON_DATE_SOMEONE_WROTE_REGEXES = [
15
16
  # Chinese
16
17
  /^[[:blank:]<>-]*在 (?:(?!\b(?>在|写道)\b).)+?写道[[:blank:].:>-]*$/im,
17
18
  # Dutch
@@ -72,7 +73,7 @@ class EmbeddedEmailMatcher
72
73
  end
73
74
 
74
75
  # Max Mustermann <try_discourse@discoursemail.com> schrieb am Fr., 28. Apr. 2017 um 11:53 Uhr:
75
- SOMEONE_WROTE_ON_DATE_REGEXES ||= [
76
+ SOMEONE_WROTE_ON_DATE_REGEXES = [
76
77
  # English
77
78
  /^.+\bwrote\b[[:space:]]+\bon\b.+[^:]+:/,
78
79
  # German
@@ -86,7 +87,7 @@ class EmbeddedEmailMatcher
86
87
  # 2013/10/2 camilohollanda <info@discourse.org>
87
88
  # вт, 5 янв. 2016 г. в 23:39, Erlend Sogge Heggen <info@discourse.org>:
88
89
  # ср, 1 апр. 2015, 18:29, Denis Didkovsky <info@discourse.org>:
89
- DATE_SOMEONE_EMAIL_REGEX = /\d{4}.{1,80}\s?<[^@<>]+@[^@<>.]+\.[^@<>]+>:?$/
90
+ DATE_SOMEONE_EMAIL_REGEX = /(?!.*<img\b)\d{4}.{1,80}\s?<[^@<>]+@[^@<>.]+\.[^@<>]+>:?$/i
90
91
 
91
92
  # codinghorror via Discourse Meta wrote:
92
93
  # codinghorror via Discourse Meta <info@discourse.org> schrieb:
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class EmptyLineMatcher
2
3
 
3
4
  def self.match?(line)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class QuoteMatcher
2
3
 
3
4
  def self.match?(line)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class SignatureMatcher
2
3
 
3
4
  # Envoyé depuis mon iPhone
@@ -13,7 +14,7 @@ class SignatureMatcher
13
14
  # (sent from a phone)
14
15
  # (Sent from mobile device)
15
16
  # 從我的 iPhone 傳送
16
- SIGNATURE_REGEXES ||= [
17
+ SIGNATURE_REGEXES = [
17
18
  # Chinese
18
19
  /^[[:blank:]]*從我的 iPhone 傳送/i,
19
20
  # English
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  require_relative "email_reply_trimmer/empty_line_matcher"
2
3
  require_relative "email_reply_trimmer/delimiter_matcher"
3
4
  require_relative "email_reply_trimmer/signature_matcher"
4
5
  require_relative "email_reply_trimmer/embedded_email_matcher"
5
6
  require_relative "email_reply_trimmer/email_header_matcher"
6
7
  require_relative "email_reply_trimmer/quote_matcher"
8
+ require 'securerandom'
7
9
 
8
10
  class EmailReplyTrimmer
9
- VERSION = "0.1.13"
11
+ VERSION = "0.3.0"
10
12
 
11
13
  DELIMITER = "d"
12
14
  EMBEDDED = "b"
@@ -23,7 +25,7 @@ class EmailReplyTrimmer
23
25
  return EMBEDDED if EmbeddedEmailMatcher.match? line
24
26
  return EMAIL_HEADER if EmailHeaderMatcher.match? line
25
27
  return QUOTE if QuoteMatcher.match? line
26
- return TEXT
28
+ TEXT
27
29
  end
28
30
 
29
31
  def self.trim(text, split = false)
@@ -32,18 +34,26 @@ class EmailReplyTrimmer
32
34
  # do some cleanup
33
35
  preprocess!(text)
34
36
 
37
+ # stash the code blocks - replace them with hashes
38
+ text, blocks = hoist_code_blocks(text)
39
+
35
40
  # from now on, we'll work on a line-by-line basis
36
41
  lines = text.split("\n")
37
42
  lines_dup = lines.dup
38
43
 
39
- # identify content of each lines
44
+ # create a string of characters, one per line, according to the line content
40
45
  pattern = lines.map { |l| identify_line_content(l) }.join
41
46
 
42
47
  # remove everything after the first delimiter
43
48
  if pattern =~ /d/
44
49
  index = pattern =~ /d/
45
- pattern = pattern[0...index]
46
- lines = lines[0...index]
50
+ underscore_separator_before_embedded_email =
51
+ lines[index] =~ /\A_+\z/ && pattern[(index + 1)..-1] =~ /b/
52
+
53
+ unless underscore_separator_before_embedded_email
54
+ pattern = pattern[0...index]
55
+ lines = lines[0...index]
56
+ end
47
57
  end
48
58
 
49
59
  # remove all mobile signatures
@@ -70,7 +80,7 @@ class EmailReplyTrimmer
70
80
 
71
81
  # if there is an embedded email marker, followed by a huge quote
72
82
  # then take everything up to that marker
73
- if pattern =~ /te*b[eqbh]*([te]*)$/ && $1.count("t") < 7
83
+ if pattern =~ /te*b[eqbh]*([te]*)$/ && $1.count("t") < 7 && pattern !~ /bq[eqbh]*t/
74
84
  index = pattern =~ /te*b[eqbh]*[te]*$/
75
85
  pattern = pattern[0..index]
76
86
  lines = lines[0..index]
@@ -123,6 +133,9 @@ class EmailReplyTrimmer
123
133
  # results
124
134
  trimmed = lines.join("\n").strip
125
135
 
136
+ # re-inject code blocks
137
+ blocks.each { |token, block| trimmed.gsub!(token, block) }
138
+
126
139
  if split
127
140
  [trimmed, compute_elided(lines_dup, lines)]
128
141
  else
@@ -151,12 +164,25 @@ class EmailReplyTrimmer
151
164
 
152
165
  if index
153
166
  before = lines[0...(pattern[0...index] =~ /e*(b[eqd]*|b*[ed]*)$/)].join("\n").strip
154
- return [embedded, before]
167
+ [embedded, before]
155
168
  end
156
169
  end
157
170
 
158
171
  private
159
172
 
173
+ def self.hoist_code_blocks(text)
174
+ blocks = {}
175
+ pattern = /^```\w*$\n.*?^```$/m
176
+
177
+ text.gsub!(pattern) do |block|
178
+ token = SecureRandom.hex
179
+ blocks[token] = block
180
+ token
181
+ end
182
+
183
+ [text, blocks]
184
+ end
185
+
160
186
  def self.preprocess!(text)
161
187
  # normalize line endings
162
188
  text.gsub!("\r\n", "\n")
File without changes
@@ -0,0 +1,3 @@
1
+ Am 13.05.2026 um 09:05 schrieb Vorname Nachname:
2
+ > Hier steht der alte Nachrichtentext.
3
+ > Dieser Text gehört vollständig zur alten Nachricht.
@@ -0,0 +1,6 @@
1
+ ----- Original Message -----
2
+ From: Firstname Lastname <name@example.test>
3
+ Date: July 28, 2026
4
+ Subject: Example
5
+
6
+ This is the previous message.
@@ -0,0 +1,2 @@
1
+ On July 28, 2026, Firstname Lastname wrote:
2
+ > This is the previous quoted message.
@@ -0,0 +1,2 @@
1
+ On July 28, 2026, Firstname Lastname wrote:
2
+ > This is the previous quoted message.
@@ -0,0 +1 @@
1
+ Am 13.05.2026 um 09:05 schrieb Vorname Nachname:
@@ -0,0 +1,2 @@
1
+ On July 28, 2026, Firstname Lastname wrote:
2
+ > This is the previous quoted message.
@@ -0,0 +1,13 @@
1
+ This is a long email with embedded code.
2
+
3
+ ```
4
+ # This should not be deleted
5
+ #
6
+
7
+ # Or trimmed
8
+ # It is code
9
+ ####
10
+ Code code code
11
+ ```
12
+
13
+ End of the email.
@@ -0,0 +1,10 @@
1
+ Hallo Vorname,
2
+
3
+ hier ist meine neue Antwort.
4
+
5
+ Viele Grüße
6
+ Vorname Nachname
7
+
8
+ Am 13.05.2026 um 09:05 schrieb Vorname Nachname:
9
+ > Hier steht der alte Nachrichtentext.
10
+ > Dieser Text gehört vollständig zur alten Nachricht.
@@ -0,0 +1,8 @@
1
+ This is my new reply.
2
+
3
+ ----- Original Message -----
4
+ From: Firstname Lastname <name@example.test>
5
+ Date: July 28, 2026
6
+ Subject: Example
7
+
8
+ This is the previous message.
@@ -0,0 +1,13 @@
1
+ Hello Firstname,
2
+
3
+ This is the first part of the new reply.
4
+
5
+ ________________________________________________________________________________
6
+
7
+ This is the second part of the new reply.
8
+
9
+ Best regards,
10
+ Firstname Lastname
11
+
12
+ On July 28, 2026, Firstname Lastname wrote:
13
+ > This is the previous quoted message.
@@ -0,0 +1,15 @@
1
+ Hello Firstname,
2
+
3
+ This is text before the inline image.
4
+
5
+ **Screenshot**
6
+
7
+ Image reference 2064 <img apple-inline="yes" id="A34F880A-3D2D-41B4-A4EE-22EA00C25DB3" src="cid:EBAE619D-7B1D-47E7-A652-BDB94969843A@example.test" class="">
8
+
9
+ This is text after the inline image.
10
+
11
+ Best regards,
12
+ Firstname Lastname
13
+
14
+ On July 28, 2026, Firstname Lastname wrote:
15
+ > This is the previous quoted message.
@@ -0,0 +1,9 @@
1
+ Hallo Vorname,
2
+
3
+ Am 13.05.2026 um 09:05 schrieb Vorname Nachname:
4
+ > Hier steht der zitierte Text.
5
+
6
+ Hier ist der Antworttext. Dieser wurde bisher abgeschnitten.
7
+
8
+ Viele Grüße
9
+ Vorname Nachname
@@ -0,0 +1,12 @@
1
+ Hello Firstname,
2
+
3
+ This is text before the inline images.
4
+
5
+ <img src="cid:first-image@example.test">
6
+ <img src="cid:second-image@example.test">
7
+ <img src="cid:third-image@example.test">
8
+
9
+ This is text after the inline images.
10
+
11
+ On July 28, 2026, Firstname Lastname wrote:
12
+ > This is the previous quoted message.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "minitest/autorun"
2
3
  require "email_reply_trimmer"
3
4
  require "timeout"
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require "minitest/autorun"
3
+ require "timeout"
2
4
  require "email_reply_trimmer"
3
5
 
4
6
  class TestEmailReplyTrimmer < Minitest::Test
@@ -0,0 +1,13 @@
1
+ This is a long email with embedded code.
2
+
3
+ ```
4
+ # This should not be deleted
5
+ #
6
+
7
+ # Or trimmed
8
+ # It is code
9
+ ####
10
+ Code code code
11
+ ```
12
+
13
+ End of the email.
@@ -0,0 +1,6 @@
1
+ Hallo Vorname,
2
+
3
+ hier ist meine neue Antwort.
4
+
5
+ Viele Grüße
6
+ Vorname Nachname
@@ -0,0 +1 @@
1
+ This is my new reply.
@@ -0,0 +1,10 @@
1
+ Hello Firstname,
2
+
3
+ This is the first part of the new reply.
4
+
5
+ ________________________________________________________________________________
6
+
7
+ This is the second part of the new reply.
8
+
9
+ Best regards,
10
+ Firstname Lastname
@@ -0,0 +1,12 @@
1
+ Hello Firstname,
2
+
3
+ This is text before the inline image.
4
+
5
+ **Screenshot**
6
+
7
+ Image reference 2064 <img apple-inline="yes" id="A34F880A-3D2D-41B4-A4EE-22EA00C25DB3" src="cid:EBAE619D-7B1D-47E7-A652-BDB94969843A@example.test" class="">
8
+
9
+ This is text after the inline image.
10
+
11
+ Best regards,
12
+ Firstname Lastname
@@ -0,0 +1,8 @@
1
+ Hallo Vorname,
2
+
3
+ > Hier steht der zitierte Text.
4
+
5
+ Hier ist der Antworttext. Dieser wurde bisher abgeschnitten.
6
+
7
+ Viele Grüße
8
+ Vorname Nachname
@@ -0,0 +1,9 @@
1
+ Hello Firstname,
2
+
3
+ This is text before the inline images.
4
+
5
+ <img src="cid:first-image@example.test">
6
+ <img src="cid:second-image@example.test">
7
+ <img src="cid:third-image@example.test">
8
+
9
+ This is text after the inline images.
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: email_reply_trimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Régis Hanol
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2020-06-04 00:00:00.000000000 Z
10
+ date: 2026-07-31 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rake
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '12'
18
+ version: '13'
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '12'
25
+ version: '13'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: minitest
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -42,20 +41,34 @@ dependencies:
42
41
  name: rubocop
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - "~>"
44
+ - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: 0.52.1
46
+ version: '0'
48
47
  type: :development
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
- - - "~>"
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rubocop-discourse
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
53
66
  - !ruby/object:Gem::Version
54
- version: 0.52.1
67
+ version: '0'
55
68
  description: EmailReplyTrimmer is a small library to trim replies from plain text
56
69
  email.
57
70
  email:
58
- - regis+rubygems@hanol.fr
71
+ - rubygems@hanol.fr
59
72
  executables: []
60
73
  extensions: []
61
74
  extra_rdoc_files: []
@@ -82,6 +95,10 @@ files:
82
95
  - test/before/forwarded_apple.txt
83
96
  - test/before/forwarded_gmail.txt
84
97
  - test/before/forwarded_message.txt
98
+ - test/elided/block_code_spacers.txt
99
+ - test/elided/complete_german_quote_at_end.txt
100
+ - test/elided/delimiter_before_forwarded_message.txt
101
+ - test/elided/delimiter_inside_new_reply.txt
85
102
  - test/elided/delimiters.txt
86
103
  - test/elided/dual_embedded.txt
87
104
  - test/elided/email_headers_1.txt
@@ -135,16 +152,23 @@ files:
135
152
  - test/elided/forwarded_apple.txt
136
153
  - test/elided/forwarded_gmail.txt
137
154
  - test/elided/forwarded_message.txt
155
+ - test/elided/inline_images_before_reply_text.txt
138
156
  - test/elided/normalize_line_endings.txt
139
157
  - test/elided/quote_and_text.txt
140
158
  - test/elided/quote_only.txt
159
+ - test/elided/reply_after_selected_german_quote.txt
141
160
  - test/elided/retains_spaces_and_formatting.txt
161
+ - test/elided/separate_inline_images_before_reply_text.txt
142
162
  - test/elided/signatures.txt
143
163
  - test/elided/spam_1.txt
144
164
  - test/elided/spam_2.txt
145
165
  - test/elided/strip.txt
146
166
  - test/elided/text_only.txt
147
167
  - test/elided/usenet.txt
168
+ - test/emails/block_code_spacers.txt
169
+ - test/emails/complete_german_quote_at_end.txt
170
+ - test/emails/delimiter_before_forwarded_message.txt
171
+ - test/emails/delimiter_inside_new_reply.txt
148
172
  - test/emails/delimiters.txt
149
173
  - test/emails/dual_embedded.txt
150
174
  - test/emails/email_headers_1.txt
@@ -198,10 +222,13 @@ files:
198
222
  - test/emails/forwarded_apple.txt
199
223
  - test/emails/forwarded_gmail.txt
200
224
  - test/emails/forwarded_message.txt
225
+ - test/emails/inline_images_before_reply_text.txt
201
226
  - test/emails/normalize_line_endings.txt
202
227
  - test/emails/quote_and_text.txt
203
228
  - test/emails/quote_only.txt
229
+ - test/emails/reply_after_selected_german_quote.txt
204
230
  - test/emails/retains_spaces_and_formatting.txt
231
+ - test/emails/separate_inline_images_before_reply_text.txt
205
232
  - test/emails/signatures.txt
206
233
  - test/emails/spam_1.txt
207
234
  - test/emails/spam_2.txt
@@ -221,6 +248,10 @@ files:
221
248
  - test/matchers/does_not_contain_embedded_email.txt
222
249
  - test/test_email_matcher.rb
223
250
  - test/test_email_reply_trimmer.rb
251
+ - test/trimmed/block_code_spacers.txt
252
+ - test/trimmed/complete_german_quote_at_end.txt
253
+ - test/trimmed/delimiter_before_forwarded_message.txt
254
+ - test/trimmed/delimiter_inside_new_reply.txt
224
255
  - test/trimmed/delimiters.txt
225
256
  - test/trimmed/dual_embedded.txt
226
257
  - test/trimmed/email_headers_1.txt
@@ -274,10 +305,13 @@ files:
274
305
  - test/trimmed/forwarded_apple.txt
275
306
  - test/trimmed/forwarded_gmail.txt
276
307
  - test/trimmed/forwarded_message.txt
308
+ - test/trimmed/inline_images_before_reply_text.txt
277
309
  - test/trimmed/normalize_line_endings.txt
278
310
  - test/trimmed/quote_and_text.txt
279
311
  - test/trimmed/quote_only.txt
312
+ - test/trimmed/reply_after_selected_german_quote.txt
280
313
  - test/trimmed/retains_spaces_and_formatting.txt
314
+ - test/trimmed/separate_inline_images_before_reply_text.txt
281
315
  - test/trimmed/signatures.txt
282
316
  - test/trimmed/spam_1.txt
283
317
  - test/trimmed/spam_2.txt
@@ -288,7 +322,6 @@ homepage: https://github.com/discourse/email_reply_trimmer
288
322
  licenses:
289
323
  - MIT
290
324
  metadata: {}
291
- post_install_message:
292
325
  rdoc_options: []
293
326
  require_paths:
294
327
  - lib
@@ -303,8 +336,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
303
336
  - !ruby/object:Gem::Version
304
337
  version: '0'
305
338
  requirements: []
306
- rubygems_version: 3.0.3
307
- signing_key:
339
+ rubygems_version: 4.0.10
308
340
  specification_version: 4
309
341
  summary: Library to trim replies from plain text email.
310
342
  test_files: []