class Hermes::URLText

URL-able representation

What's acually happening

URLs may not contain spaces and serveral character as slashes, ampersands etc. These characters will be masked by a percent sign and two hex digits representing the ASCII code. Eight bit characters should be masked the same way.

An URL line does not store encoding information by itself. A locator may either say one of these:

http://www.example.com/subdir/index.html?umlfield=%C3%BCber+alles
http://www.example.com/subdir/index.html?umlfield=%FCber+alles

The reading CGI has to decide on itself how to treat it.

Examples

URLText.encode "'Stop!' said Fred."     #=> "%27Stop%21%27+said+Fred."
URLText.decode "%27Stop%21%27+said+Fred%2e"
                                        #=> "'Stop!' said Fred."

Attributes

keep_8bit[RW]
keep_space[RW]
mask_space[RW]

Public Class Methods

new( hash) → urltext click to toggle source

Creates a URLText converter.

The parameters may be given as values or as a hash.

utx = URLText.new :keep_8bit => true, :keep_space => false

See the encode method for an explanation of these parameters.

# File lib/hermes/escape.rb, line 279
def initialize hash = nil
  if hash then
    @keep_8bit  = hash[ :keep_8bit ]
    @keep_space = hash[ :keep_space]
    @mask_space = hash[ :mask_space]
  end
end

Public Instance Methods

decode(str) click to toggle source
# File lib/hermes/escape.rb, line 428
def decode str
  self.class.decode str
end
decode_hash(qstr, &block) click to toggle source
# File lib/hermes/escape.rb, line 432
def decode_hash qstr, &block
  self.class.decode_hash qstr, &block
end
encode( str) → str click to toggle source

Create a string that contains %XX-encoded bytes.

utx = URLText.new
utx.encode "'Stop!' said Fred."       #=> "%27Stop%21%27+said+Fred."

The result will not contain any 8-bit characters, except when keep_8bit is set. The result will be in the same encoding as the argument although this normally has no meaning.

utx = URLText.new :keep_8bit => true
s = "< ä >".encode "UTF-8"
utx.encode s                    #=> "%3C+\u{e4}+%3E"  in UTF-8

s = "< ä >".encode "ISO-8859-1"
utx.encode s                    #=> "%3C+\xe4+%3E"      in ISO-8859-1

A space " " will not be replaced by a plus "+" if keep_space is set.

utx = URLText.new :keep_space => true
s = "< x >"
utx.encode s                    #=> "%3C x %3E"

When mask_space is set, then a space will be represented as "%20",

# File lib/hermes/escape.rb, line 316
def encode str
  r = str.new_string
  r.force_encoding Encoding::ASCII_8BIT unless @keep_8bit
  r.gsub! /([^a-zA-Z0-9_.-])/ do |c|
    if c == " " and not @mask_space then
      @keep_space ? c : "+"
    elsif not @keep_8bit or c.ascii_only? then
      "%%%02X" % c.ord
    else
      c
    end
  end
  r.encode! str.encoding
end
encode_hash( hash) → str click to toggle source

Encode a Hash to a URL-style string.

utx = URLText.new

h = { :name => "John Doe", :age => 42 }
utx.encode_hash h
    #=> "name=John+Doe&age=42"

h = { :a => ";;;", :x => "äöü" }
utx.encode_hash h
    #=> "a=%3B%3B%3B&x=%C3%A4%C3%B6%C3%BC"
# File lib/hermes/escape.rb, line 395
def encode_hash hash
  hash.map { |(k,v)|
    case v
      when nil   then next
      when true  then v = k
      when false then v = ""
    end
    [k, v].map { |x| encode x.to_s }.join PAIR_SET
  }.compact.join PAIR_SEP
end
mkurl( path, hash, anchor = nil) → str click to toggle source

Make an URL.

utx = URLText.new
h = { :name => "John Doe", :age => "42" }
utx.encode_hash "myscript.rb", h, "chapter"
    #=> "myscript.rb?name=John+Doe&age=42#chapter"
# File lib/hermes/escape.rb, line 416
def mkurl path, hash = nil, anchor = nil
  unless Hash === hash then
    hash, anchor = anchor, hash
  end
  r = "#{path}"
  r << "?#{encode_hash hash}" if hash
  r << "##{anchor}" if anchor
  r
end
std() click to toggle source
# File lib/hermes/escape.rb, line 438
def std
  @std ||= new
end

Private Instance Methods

each_pair(qstr) { |*kv| ... } click to toggle source
# File lib/hermes/escape.rb, line 513
def each_pair qstr
  qstr or return
  h = qstr.to_s.split PAIR_SEP
  h.each do |pair|
    kv = pair.split PAIR_SET, 2
    kv.map! { |x| decode x if x }
    yield *kv
  end
end