Class: Hermeneutics::HeaderExt

Inherits:
Object
  • Object
show all
Defined in:
lib/hermeneutics/escape.rb

Overview

Header field contents (RFC 2047) encoding

Examples

HeaderExt.encode "Jörg Müller"
                              #=> "=?utf-8?Q?J=C3=B6rg_M=C3=BCller?="
HeaderExt.decode "=?UTF-8?Q?J=C3=B6rg_M=C3=BCller?="
                              #=> "Jörg Müller"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = nil) ⇒ HeaderExt

:call-seq:

new( [ parameters] )    -> con

Creates a HeaderExt converter.

See the encode method for an explanation of the parameters.

Examples

con = HeaderExt.new
con = HeaderExt.new base64: true, limit: 32, lower: true
con = HeaderExt.new mask: /["'()]/


538
539
540
541
542
543
544
545
546
547
# File 'lib/hermeneutics/escape.rb', line 538

def initialize params = nil
  if params then
    @base64 = params.delete :base64
    @limit  = params.delete :limit
    @lower  = params.delete :lower
    @mask   = params.delete :mask
    params.empty? or
      raise ArgumentError, "invalid parameter: #{params.keys.first}."
  end
end

Class Method Details

.decode(str) ⇒ Object

:call-seq:

decode( str)     -> str

Remove header field style escapes.

HeaderExt.decode "=?UTF-8?Q?J=C3=B6rg_M=C3=BCller?="
                              #=> "Jörg Müller"


728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
# File 'lib/hermeneutics/escape.rb', line 728

def decode str
  r, e = [], []
  loop do
    if str =~ /=\?([a-z0-9_-]+?)\?([QB])\?([!-~]+?)\?=/i then
      p = $`
      d = unmask $1, $2, $3
      str = $'
    else
      p = str
    end
    r.push p if p =~ /\S/
    d or break
    r.push d
    e.push d.encoding
  end
  e.uniq!
  begin
    r.join
  rescue EncodingError
    raise if e.empty?
    f = e.shift
    r.each { |x| x.encode! f }
    retry
  end
end

.encode(str) ⇒ Object

:call-seq:

encode( str)   -> str

Use the standard content encoding.



707
708
709
# File 'lib/hermeneutics/escape.rb', line 707

def encode str
  std.encode str
end

.encode_whole(str) ⇒ Object

:call-seq:

encode_whole( str)   -> str

Use the standard content encoding.



716
717
718
# File 'lib/hermeneutics/escape.rb', line 716

def encode_whole str
  std.encode_whole str
end

.needs?(str) ⇒ Boolean

:call-seq:

needs? str  -> true or false

Use the standard content encoding.

Returns:

  • (Boolean)


698
699
700
# File 'lib/hermeneutics/escape.rb', line 698

def needs? str
  std.needs? str
end

.stdObject

The standard header content encoding has a word break limit of 64.



689
690
691
# File 'lib/hermeneutics/escape.rb', line 689

def std
  @std ||= new limit: 64
end

Instance Method Details

#decode(str) ⇒ Object



681
682
683
# File 'lib/hermeneutics/escape.rb', line 681

def decode str
  self.class.decode str
end

#encode(str) ⇒ Object

:call-seq:

encode( str)   -> str

Create a header field style encoded string. The following parameters will be evaluated:

:base64    # build ?B? instead of ?Q?
:limit     # break words longer than this
:lower     # build lower case ?b? and ?q?
:mask      # a regular expression detecting characters to mask

The result will not contain any 8-bit characters. The encoding will be kept although it won’t have a meaning.

The parameter :mask will have no influence on the masking itself but will guarantee characters to be masked.

Examples

yodel = "Holleri du dödl di, diri diri dudl dö."

con = HeaderExt.new
con.encode yodel
  #=> "Holleri du =?UTF-8?Q?d=C3=B6dl?= di, diri diri dudl =?UTF-8?Q?d=C3=B6=2E?="

yodel.encode! "iso8859-1"
con.encode yodel
  #=> "Holleri du =?ISO8859-1?Q?d=F6dl?= di, diri diri dudl =?ISO8859-1?Q?d=F6=2E?="

e = ""
e.encode! "utf-8"      ; con.encode e      #=> "=?UTF-8?Q?=E2=82=AC?="
e.encode! "iso8859-15" ; con.encode e      #=> "=?ISO8859-15?Q?=A4?="
e.encode! "ms-ansi"    ; con.encode e      #=> "=?MS-ANSI?Q?=80?="

con = HeaderExt.new mask: /["'()]/
con.encode "'Stop!' said Fred."
  #=> "=?UTF-8?Q?=27Stop=21=27?= said Fred."


596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
# File 'lib/hermeneutics/escape.rb', line 596

def encode str
  do_encoding str do
    # I don't like this kind of programming style but it seems to work. BS
    r, enc = "", ""
    while str =~ /\S+/ do
      if needs? $& then
        (enc.notempty? || r) << $`
        enc << $&
      else
        if not enc.empty? then
          r << (mask enc)
          enc.clear
        end
        r << $` << $&
      end
      str = $'
    end
    if not enc.empty? then
      enc << str
      r << (mask enc)
    else
      r << str
    end
    r
  end
end

#encode_whole(str) ⇒ Object

:call-seq:

encode_whole( str)   -> str

The unlike encode the whole string as one piece will be encoded.

yodel = "Holleri du dödl di, diri diri dudl dö."
HeaderExt.encode_whole yodel
  #=> "=?UTF-8?Q?Holleri_du_d=C3=B6dl_di,_diri_diri_dudl_d=C3=B6=2E?="


632
633
634
635
636
# File 'lib/hermeneutics/escape.rb', line 632

def encode_whole str
  do_encoding str do
    mask str
  end
end

#needs?(str) ⇒ Boolean

:call-seq:

needs? str  -> true or false

Check whether a string needs encoding.

Returns:

  • (Boolean)


554
555
556
# File 'lib/hermeneutics/escape.rb', line 554

def needs? str
  (not str.ascii_only? or str =~ @mask) and true or false
end