1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#
# == Content Formats
#
# [Text/Plain Flowed] TextFlowed
# [Quoted-Printable] To be implemented ...
# [Base64] To be implemented ...
#
module MIME::ContentFormats
#
# Minimal implementation of RFC 2646: The Text/Plain Format Parameter
#
# https://tools.ietf.org/html/rfc2646
#
# == Excerpts from RFC
#
# This memo proposes a new parameter to be used with Text/Plain, and, in the
# presence of this parameter, the use of trailing whitespace to indicate
# flowed lines. This results in an encoding which appears as normal
# Text/Plain in older implementations, since it is in fact normal
# Text/Plain.
#
# Each paragraph is displayed, starting at the left margin (or paragraph
# indent), and continuing to the right until a word is encountered which
# does not fit in the remaining display width. This word is displayed at the
# left margin of the next line. This continues until the paragraph ends (a
# CRLF is seen).
#
# == MIME format parameter to the text/plain media type
#
# Name: Format
# Value: Fixed, Flowed
# Example: Content-Type: text/plain; charset=iso-8859-1; format=flowed
#
#--
# == TODO
# - Implement RFC 3676, which obsoletes RFC 2646.
# - Usenet signature convention (section 4.3)
# - Space-Stuffing (section 4.4)
# - Quoting (section 4.5)
# - Perhaps this should be subsumed into the MIME project.
#
module TextFlowed
MAX_FLOWED_LINE = 79
#
# Encode plain +text+ into flowed format, reducing long lines to +max+
# characters or less using soft line breaks (i.e., SPACE+CRLF).
#
# According to the RFC, the +max+ flowed line length is 79 characters. Line
# lengths of 66 and 72 characters are common.
#
# The features of RFC 2646, such as line quoting and space-stuffing,
# are not implemented.
#
def self.encode(text, max = MAX_FLOWED_LINE)
if max > MAX_FLOWED_LINE
raise ArgumentError, "flowed lines must be #{MAX_FLOWED_LINE} characters or less"
end
out = []
text.split(/\r\n|\n/).each do |paragraph|
# tab use is discouraged
# http://tools.ietf.org/html/rfc822#section-3.4.2
paragraph.gsub!(/\t/, ' '*4)
# trim spaces before hard break
# http://tools.ietf.org/html/rfc2646#section-4.1
paragraph.rstrip!
if paragraph.length <= max
out << paragraph
else # flow text
line = ''
word = ''
paragraph.each_char do |char|
if char == ' '
# Omit spaces after soft break to prevent stuffing on next line.
next if word.empty? && (line.size == 0 || line.size == max)
if (line.size + word.size) < max
line << word + char
else # soft break situation
unless line.empty?
out << line.dup
line.clear
end
if word.size < max
line << word + char
else
word.scan(/.{1,#{MIME::MAX_LINE_LENGTH}}/) {|s| out << s }
end
end
word.clear
else # accumulate non-space characters in buffer
word += char
end
end
# flush buffers in an orderly fashion
if ! word.empty?
if (line.size + word.size) <= max
out << line + word
else
out << line unless line.empty?
word.scan(/.{1,#{MIME::MAX_LINE_LENGTH}}/) {|s| out << s }
end
elsif ! line.empty?
out << line
end
end
end
out.join("\r\n")
end
#
# Decode flowed plain +text+.
#
def self.decode(text)
raise NotImplementedError
end
end
end
|