class EmailReplyParser::Email

An Email instance represents a parsed body String.

Constants

EMPTY
SIGNATURE
SIG_REGEX

Attributes

fragments[R]

Emails have an Array of Fragments.

Public Instance Methods

read(text) click to toggle source

Splits the given text into a list of Fragments. This is roughly done by reversing the text and parsing from the bottom to the top. This way we can check for ‘On <date>, <author> wrote:’ lines above quoted blocks.

text - A String email body.

Returns this same Email instance.

# File lib/email_reply_parser.rb, line 78
def read(text)
  text = text.dup

  # Normalize line endings.
  text.gsub!("\r\n", "\n")

  # Check for multi-line reply headers. Some clients break up
  # the "On DATE, NAME <EMAIL> wrote:" line into multiple lines.
  if text =~ /^(?!On.*On\s.+?wrote:)(On\s(.+?)wrote:)$/
    # Remove all new lines from the reply header.
    text.gsub! $1, $1.gsub("\n", " ")
  end

  # Some users may reply directly above a line of underscores.
  # In order to ensure that these fragments are split correctly,
  # make sure that all lines of underscores are preceded by
  # at least two newline characters.
  text.gsub!(/([^\n])(?=\n_{7}_+)$/, "\\1\n")

  # The text is reversed initially due to the way we check for hidden
  # fragments.
  text = text.reverse

  # This determines if any 'visible' Fragment has been found.  Once any
  # visible Fragment is found, stop looking for hidden ones.
  @found_visible = false

  # This instance variable points to the current Fragment.  If the matched
  # line fits, it should be added to this Fragment.  Otherwise, finish it
  # and start a new Fragment.
  @fragment = nil

  # Use the StringScanner to pull out each line of the email content.
  @scanner = StringScanner.new(text)
  while line = @scanner.scan_until(/\n/)
    scan_line(line)
  end

  # Be sure to parse the last line of the email.
  if (last_line = @scanner.rest.to_s).size > 0
    scan_line(last_line)
  end

  # Finish up the final fragment.  Finishing a fragment will detect any
  # attributes (hidden, signature, reply), and join each line into a
  # string.
  finish_fragment

  @scanner = @fragment = nil

  # Now that parsing is done, reverse the order.
  @fragments.reverse!
  self
end
visible_text() click to toggle source

Public: Gets the combined text of the visible fragments of the email body.

Returns a String.

# File lib/email_reply_parser.rb, line 67
def visible_text
  fragments.select{|f| !f.hidden?}.map{|f| f.to_s}.join("\n").rstrip
end

Public Class Methods

new() click to toggle source
# File lib/email_reply_parser.rb, line 60
def initialize
  @fragments = []
end