diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/init.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/init.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/init.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/init.rb 2004-04-21 23:29:38.000000000 +0200
@@ -0,0 +1,40 @@
+require "rbconfig"
+
+Reversed = (ARGV.include?("-r"))
+
+FromDirs = ENV["PATH"].split(/:/) + [".", "./lib", "./rubylib/lib"]
+ToDir = Config::CONFIG["sitelibdir"] + "/ev"
+
+Dir.mkdir(ToDir) if not File.directory?(ToDir)
+
+FromDirs.each do |fromdir|
+ fromdir = Dir.pwd if fromdir == "."
+ if File.directory?(fromdir)
+ Dir.new(fromdir).each do |file|
+ if not file.scan(/\.lib\.rb$/).empty?
+ fromfile = fromdir + "/" + file
+ tofile = ToDir + "/" + file.sub(/\.lib\.rb/, ".rb")
+
+ if not (File.directory?("c:/"))
+ printf "%s -> %s\n", fromfile, tofile
+
+ File.unlink(tofile) if File.symlink?(tofile)
+ File.symlink(fromfile, tofile)
+ else
+ if Reversed
+ tofile, fromfile = fromfile, tofile
+ end
+
+ if FileTest.file?(fromfile)
+ printf "%s -> %s\n", fromfile, tofile
+
+ File.delete(tofile) if File.writable?(tofile)
+ File.open(tofile, "w") {|f| f.puts File.new(fromfile).readlines}
+ else
+ printf "%s -> %s (Skipped!)\n", fromfile, tofile
+ end
+ end
+ end
+ end
+ end
+end
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/install.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/install.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/install.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/install.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,40 @@
+require "rbconfig"
+
+Reversed = (ARGV.include?("-r"))
+
+FromDirs = ENV["PATH"].split(/:/) + [".", "./lib", "./rubylib/lib"]
+ToDir = Config::CONFIG["sitelibdir"] + "/ev"
+
+Dir.mkdir(ToDir) if not File.directory?(ToDir)
+
+FromDirs.each do |fromdir|
+ fromdir = Dir.pwd if fromdir == "."
+ if File.directory?(fromdir)
+ Dir.new(fromdir).each do |file|
+ if not file.scan(/\.lib\.rb$/).empty?
+ fromfile = fromdir + "/" + file
+ tofile = ToDir + "/" + file.sub(/\.lib\.rb/, ".rb")
+
+ if not (File.directory?("c:/"))
+ printf "%s -> %s\n", fromfile, tofile
+
+ File.unlink(tofile) if File.symlink?(tofile)
+ File.symlink(fromfile, tofile)
+ else
+ if Reversed
+ tofile, fromfile = fromfile, tofile
+ end
+
+ if FileTest.file?(fromfile)
+ printf "%s -> %s\n", fromfile, tofile
+
+ File.delete(tofile) if File.writable?(tofile)
+ File.open(tofile, "w") {|f| f.puts File.new(fromfile).readlines}
+ else
+ printf "%s -> %s (Skipped!)\n", fromfile, tofile
+ end
+ end
+ end
+ end
+ end
+end
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/net.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/net.lib.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/net.lib.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/net.lib.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,541 @@
+require "ev/ruby"
+#alias old_timeout :timeout
+require "net/http"
+#alias timeout :old_timeout
+require "socket"
+require "uri"
+require "cgi"
+require "md5"
+require "thread"
+
+file = "#{home}/.evnet"
+if File.file?(file)
+ Hash.file(file).each do |k, v|
+ eval "$#{k} = ´#{v}´" unless k=~ /^\#/
+ #$proxy_auth = [$proxy_auth].pack("m").chomp if k == "proxy_auth"
+ end
+end
+
+def uri2txt(s)
+ i = s.index(/%[[:digit:]]{2}/)
+ while not i.nil?
+ s = s[0..(i-1)] + s[(i+1)..(i+2)].unpack(´H2´).shift.to_i.chr + s[(i+3)..-1]
+ i = s.index(/%[[:digit:]]{2}/)
+ end
+ s
+end
+
+class EVURI
+ attr_reader :protocol
+ attr_writer :protocol
+ attr_reader :userpass
+ attr_writer :userpass
+ attr_reader :host
+ attr_writer :host
+ attr_reader :port
+ attr_writer :port
+ attr_reader :path
+ attr_writer :path
+ attr_reader :vars
+ attr_writer :vars
+ attr_reader :anchor
+ attr_writer :anchor
+
+ def initialize(url)
+ begin
+ @protocol, @userpass, @host, @port, d1, @path, d2, @vars, @anchor = URI.split(url.to_s)
+ rescue
+ end
+
+ @protocol = "" if @protocol.nil?
+ @userpass = "" if @userpass.nil?
+ @host = "" if @host.nil?
+ @port = 0 if @port.nil?
+ @path = "" if @path.nil?
+ @vars = "" if @vars.nil?
+ @anchor = "" if @anchor.nil?
+
+ res = {}
+ @varsvolgorde = []
+ @vars.split(/&/).each{|var| k, v = var.split(/=/) ; res[k] = v ; @varsvolgorde << k}
+ @vars = res
+
+ @port = @port.to_i
+ end
+
+ def + (url2)
+ url1 = self.to_s
+ url2 = url2.to_s if url2.kind_of?(self.class)
+
+ return EVURI.new((URI::Generic.new(*URI.split(url1)) + URI::Generic.new(*URI.split(url2))).to_s) rescue nil
+ end
+
+ def to_s
+ protocol = @protocol
+ userpass = @userpass
+ host = @host
+ port = @port.to_s
+ path = @path
+ vars = varstring
+ anchor = @anchor
+
+ protocol = nil if @protocol.empty?
+ userpass = nil if @userpass.empty?
+ host = nil if @host.empty?
+ port = nil if @port.zero?
+ path = nil if @path.empty?
+ vars = nil if @vars.empty?
+ anchor = nil if @anchor.empty?
+
+ res = URI::HTTP.new(@protocol, @userpass, @host, port, nil, @path, nil, vars, @anchor).to_s
+
+ res.gsub!(/@/, "") if (@userpass.nil? or @userpass.empty?)
+
+ res.gsub!(/\#$/, "")
+
+ return res
+ end
+
+ def varstring
+ res = []
+ vars = @vars.dup
+
+ @varsvolgorde.each do |k|
+ if vars.include?(k)
+ v = vars[k]
+ vars.delete(k)
+
+ res << (v.nil? ? k : "#{k}=#{v}")
+ end
+ end
+
+ res.concat(vars.collect{|k, v| v.nil? ? k : "#{k}=#{v}"})
+
+ return res.join("&")
+ end
+end
+
+class HTTPClient
+ @@versie = 1
+ @@mutex = Mutex.new
+ @@hosts = {}
+
+ class Header
+ attr_reader :header
+ attr_reader :protocol
+ attr_reader :code
+ attr_reader :text
+
+ def initialize(header)
+ @header = {}
+
+ if not header.nil?
+ firstline, rest = header.split(/\r*\n/, 2)
+
+ @protocol, @code, @text = firstline.split(/ */, 3)
+
+ if not rest.nil?
+ rest.split(/\r*\n/).each do |line|
+ key, value = line.split(/ /, 2)
+ @header[key.sub(/:$/, "").downcase] = value
+ end
+ end
+ end
+ end
+
+ def to_s
+ res = ""
+
+ res << "%s %s %s\n" % [@protocol, @code, @text]
+
+ @header.each do |k, v|
+ res << "%s=%s\n" % [k, v]
+ end
+
+ return res
+ end
+ end
+
+ class Chunk
+ def initialize(data)
+ @data = ""
+ line, data = data.split(/\r*\n/, 2)
+ size, ext = line.split(/;/, 2)
+ size = size.hex
+ while not size.zero? and not data.nil?
+ @data += data[0..(size-1)]
+ data = data[size..-1]
+ if not data.nil?
+ data.gsub!(/^\r*\n/, "")
+ line, data = data.split(/\r*\n/, 2)
+ size, ext = line.split(/;/, 2)
+ size = size.hex
+ end
+ end
+ end
+
+ def to_s
+ @data
+ end
+ end
+
+ def self.head(uri, form={}, recursive=true)
+ header = Header.new(nil)
+
+ begin
+ while not uri.nil?
+ if $proxy.nil? or $proxy.empty?
+ uri = EVURI.new(uri) if uri.kind_of? String
+ host = uri.host
+ port = uri.port
+ io = nil
+
+ @@mutex.synchronize do
+ @@hosts[host] = IPSocket.getaddress(host) if not @@hosts.include?(host)
+ io = TCPSocket.new(@@hosts[host], port.zero? ? 80 : port)
+ end
+
+ io.write("HEAD #{uri.path or ´/´}#{uri.varstring.empty? ? ´´ : ´?´ + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\n\r\n")
+ else
+ proxy = EVURI.new($proxy)
+ host = proxy.host
+ port = proxy.port
+
+ io = TCPSocket.new(host, port.zero? ? 8080 : port)
+
+ io.write("HEAD #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}\r\n\r\n")
+ end
+
+ io.close_write
+
+ res = io.read
+ header, data = nil, nil
+ header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil?
+ header = Header.new(header)
+
+ if recursive and header.header["location"] != uri.to_s
+ uri = EVURI.new(uri) + header.header["location"]
+ else
+ uri = nil
+ end
+ end
+ rescue
+ header = Header.new(nil)
+ end
+
+ return header
+ end
+
+ def self.get(uri, form={})
+ res = Array.new
+ form.each_pair do |var, value|
+ res << "#{var.to_html}=#{value.to_html}"
+ end
+ post = res.join("?")
+
+ data = nil
+
+ begin
+ while not uri.nil?
+ if $proxy.nil? or $proxy.empty?
+ uri = EVURI.new(uri) if uri.kind_of? String
+ host = uri.host
+ port = uri.port
+ io = nil
+
+ @@mutex.synchronize do
+ @@hosts[host] = IPSocket.getaddress(host) if not @@hosts.include?(host)
+ io = TCPSocket.new(@@hosts[host], port.zero? ? 80 : port)
+ end
+
+ if post.empty?
+ io.write("GET #{uri.path or ´/´}#{uri.varstring.empty? ? ´´ : ´?´ + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\n\r\n")
+ else
+ io.write("POST #{uri.path or ´/´}#{uri.varstring.empty? ? ´´ : ´?´ + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: #{post.length}\r\n\r\n")
+ io.write(post)
+ end
+ else
+ proxy = EVURI.new($proxy)
+ host = proxy.host
+ port = proxy.port
+ io = nil
+
+ io = TCPSocket.new(host, port.zero? ? 8080 : port)
+
+ if post.empty?
+ io.write("GET #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}\r\n\r\n")
+ else
+ io.write("POST #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}Content-Type: application/x-www-form-urlencoded\r\nContent-Length: #{post.length}\r\n\r\n")
+ io.write(post)
+ end
+ end
+
+ io.close_write
+
+ res = io.read
+ header, data = nil, nil
+ header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil?
+
+ header = Header.new(header)
+
+ if header.header["location"] != uri.to_s
+ uri = EVURI.new(uri) + header.header["location"]
+ else
+ uri = nil
+ end
+
+ if header.header["transfer-encoding"] == "chunked"
+ data = Chunk.new(data).to_s if not data.nil?
+ end
+ end
+ rescue
+ data = nil
+ end
+
+ return data
+ end
+
+ def self.head_from_cache(uri, form={})
+ from_cache("head", uri, form)
+ end
+
+ def self.get_from_cache(uri, form={})
+ from_cache("get", uri, form)
+ end
+
+ def self.from_cache(action, uri, form)
+ loc = uri.to_s + form.sort.inspect
+ hash = MD5.new("#{@@versie} #{loc}")
+
+ dir = "#{temp}/evcache.#{user}/httpclient.#{action}"
+ file = "#{dir}/#{hash}"
+ data = nil
+
+ Dir.mkdirrec(dir)
+
+ expire = 356*24*60*60
+
+ if FileTest.file?(file) and (Time.new.to_f - File.stat(file).mtime.to_f < expire)
+ @@mutex.synchronize do
+ File.open(file, "rb") {|f| data = f.read}
+ end
+ else
+ data = method(action).call(uri, form)
+
+ if not data.nil?
+ @@mutex.synchronize do
+ File.open(file, "wb") {|f| f.write data}
+ end
+ end
+ end
+
+ return data
+ end
+end
+
+class RequestGet < Hash
+ def initialize(data)
+ CGI.parse(data).each do |k, v|
+ self[k] = v.join(" ")
+ end
+ end
+end
+
+class RequestPost < Hash
+ def initialize(data)
+ CGI.parse(data).each do |k, v|
+ self[k] = v.join(" ")
+ end
+ end
+end
+
+class RequestRequest
+ attr_reader :method
+ attr_reader :uri
+ attr_reader :path
+ attr_reader :data
+ attr_reader :protocol
+
+ def initialize(firstline)
+ @method, @uri, @protocol = firstline.split(/ /)
+ @path, @data = @uri.split(/\?/)
+ @data = "" if @data.nil? # TODO
+
+# i = @path.index(/%[[:digit:]]{2}/)
+# while not i.nil?
+# @path = @path[0..(i-1)] + @path[(i+1)..(i+2)].unpack(´H2´).shift.to_i.chr + @path[(i+3)..-1]
+# i = @path.index(/%[[:digit:]]{2}/)
+# end
+ end
+
+ def to_s
+ "#{@method} #{@uri} #{@protocol}\r\n"
+ end
+end
+
+class Request < Hash
+ attr_reader :peeraddr
+ attr_reader :request
+ attr_reader :cookies
+ attr_reader :vars
+
+ def initialize(io)
+ @io = io
+
+ firstline = @io.gets
+
+ return if firstline.nil?
+
+ @request = RequestRequest.new(firstline.strip)
+
+ line = @io.gets.strip
+ while not line.empty? do
+ key, value = line.split(" ", 2)
+ self[key.sub(/:$/, "").downcase] = value
+
+ line = @io.gets.strip
+ end
+
+ cookie = self["cookie"]
+ cookie = "" if cookie.nil?
+ @cookies = {}
+ cookie.split(/;/).each do |s|
+ k, v = s.strip.split(/=/, 2)
+ @cookies[k] = v
+ end
+
+ if not @request.method.nil?
+ case @request.method
+ when "HEAD"
+ when "GET"
+ @vars = RequestGet.new(@request.data.nil? ? "" : @request.data)
+ when "POST"
+ data = @io.read(self["content-length"].to_i)
+ @vars = RequestPost.new((self["content-type"] == "application/x-www-form-urlencoded") ? data : "")
+ else
+ puts "Unknown request (´#{firstline}´)."
+ end
+ end
+
+ @peeraddr = @io.peeraddr
+
+ @io.close_read
+ end
+
+ def to_s
+ res = @request.to_s
+ self.each do |k, v|
+ res << "#{k}: #{v}\r\n"
+ end
+ res
+ end
+end
+
+class Response < Hash
+ attr_writer :response
+
+ def initialize(io)
+ @io = io
+ @response = "HTTP/1.0 200 OK"
+ @data = ""
+ end
+
+ def flush
+ @io.write("#{to_s}\r\n#{@data}")
+ @io.close
+ end
+
+ def to_s
+ res = "#{@response}\r\n"
+ self.each do |k, v|
+ res << "#{k}: #{v}\r\n"
+ end
+ res
+ end
+
+ def << (s)
+ @data << s
+ end
+end
+
+class HTTPServer
+ @@times = {}
+
+ def self.serve(port=80, remote=false, auth=nil, realm="ev/net")
+ begin
+ server = TCPServer.new(remote ? "0.0.0.0" : "localhost", port)
+ puts "Just point your browser to http://localhost:#{port}/ ..."
+ rescue
+ server = nil
+ puts "Port #{port} is in use."
+ end
+
+ if not server.nil?
+ loop do
+ io = nil
+
+ begin
+ io = server.accept
+
+ req = Request.new(io)
+ resp = Response.new(io)
+ rescue
+ puts "Getting request from browser failed."
+ io = nil
+ end
+
+ if not io.nil? and not req.peeraddr.nil?
+ #Thread.new(req, resp) do |req, resp|
+ com = req.request.to_s.strip + req.peeraddr[3]
+
+ @@times[com]=Time.new.to_f if not @@times.include?(com)
+
+ if (not remote) or (remote and (auth.nil? or authenticate(auth, realm, req, resp)))
+ #puts "#{Time.new.strftime("%H:%M:%S")}: #{req.peeraddr[3]}: #{((Time.new.to_f - @@times[com]).to_s + "0"*4)[0..4]}: > #{req.request}"
+
+ yield(req, resp)
+
+ puts "#{Time.new.strftime("%H:%M:%S")}: #{req.peeraddr[3]}: #{((Time.new.to_f - @@times[com]).to_s + "0"*4)[0..4]}: < #{req.request}"
+
+ @@times.delete(com)
+ end
+
+ begin
+ resp.flush
+ rescue
+ end
+ #end
+ end
+ end
+ end
+ end
+
+ def self.authenticate(auth, realm, req, resp)
+ if auth.kind_of? String
+ file = "#{home}/#{auth}"
+ auths = {}
+ auths = Hash.file(file) if FileTest.file?(file)
+ else
+ auths = auth
+ end
+
+ authuserpassword = req["authorization"]
+ if not authuserpassword.nil?
+ authtype, userpassword = authuserpassword.split(/ /)
+ if authtype == "Basic" and not userpassword.nil?
+ u, p = userpassword.unpack("m").shift.split(/:/)
+ end
+ end
+
+ ok = (auths.include?(u) and auths[u] == p)
+
+ if ok
+
+ else
+ resp["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
+ resp.response = "HTTP/1.0 401 Unauthorized"
+ end
+
+ return ok
+ end
+end
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/ruby.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/ruby.lib.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/ruby.lib.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/ruby.lib.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,648 @@
+require "cgi"
+require "rbconfig"
+
+Thread.abort_on_exception = true
+
+module Enumerable
+ def deep_dup
+ Marshal::load(Marshal::dump(dup))
+ end
+
+ def deep_clone
+ Marshal::load(Marshal::dump(clone))
+ end
+end
+
+class Object
+ alias deep_dup :dup
+ alias deep_clone :clone
+
+ def to_fs
+ to_s
+ end
+end
+
+class Numeric
+ def to_fs
+ to_f
+ end
+end
+
+class String
+ def chomp!(dummy=nil)
+ self.gsub!(/[\r\n]*\z/, "")
+ end
+
+ def chomp(dummy=nil)
+ self.gsub(/[\r\n]*\z/, "")
+ end
+
+ def crlf
+ self.gsub(/\r*\n/, "\r\n").gsub(/\r\n\z/, "") + "\r\n"
+ end
+
+ def strip
+ self.stripbefore.stripafter
+ end
+
+ def stripbefore
+ self.gsub(/\A[[:blank:]\r\n]*/, "")
+ end
+
+ def stripafter
+ self.gsub(/[[:blank:]\r\n]*\z/, "")
+ end
+
+ def compress
+ self.gsub(/[[:blank:]\r\n]+/, " ").strip
+ end
+
+ def compressspaces
+ self.gsub(/[[:blank:]]+/, " ")
+ end
+
+ def numeric?
+ d, a, n = [self].to_par
+
+ not n.empty?
+ end
+
+ def exec(input=nil, output=true)
+ res = []
+
+ IO.popen(self, "w+") do |f|
+ f.puts input if not input.nil?
+ f.close_write
+
+ res = f.readlines if output
+ end
+
+ res.join("")
+ end
+
+ def eval
+ Kernel::eval(self)
+ end
+
+ def speak
+ require "drb"
+
+ DRb.start_service
+ DRbObject.new(nil, "druby://localhost:3100").speak(self)
+ end
+
+ def splitblocks(begindelimiters, enddelimiter)
+ bd = begindelimiters.collect {|s| Regexp.escape(s)}
+ ed = enddelimiter.collect {|s| Regexp.escape(s)}
+
+ be = bd.join("|")
+ ee = ed.join("|")
+
+ res = []
+ type = 0
+ tmp = ""
+ es = ""
+ self.split(/(#{be}|#{ee})/).each do |s|
+ if type == 0
+ if begindelimiters.include?(s)
+ type = begindelimiters.index(s)+1
+ tmp = s
+ es = enddelimiter[begindelimiters.index(s)]
+ else
+ #res << [0, s] if not s.compress.empty?
+ res << [0, s] if not s.empty?
+ end
+ else
+ if s == es
+ res << [type, tmp + s]
+ type = 0
+ tmp = ""
+ es = ""
+ else
+ tmp = tmp + s
+ end
+ end
+ end
+ res
+ end
+
+ def splitwords(tokens=[], begindelimiters=["´", ´"´], enddelimiter=["´", ´"´])
+ tokens = [tokens] if not tokens.kind_of?(Array)
+ res = []
+ self.splitblocks(begindelimiters, enddelimiter).each do |type, s|
+ case type
+ when 0
+ tokens.each do |token|
+ token2 = token
+ token2 = Regexp.escape(token2) if token2.kind_of?(String)
+ s.gsub!(/#{token2}/, " #{token} ")
+ end
+ s.split().each do |w|
+ res << w
+ end
+ when 1, 2
+ res << s[1..-2]
+ end
+ end
+ res
+ end
+
+ def uncomment
+ res = []
+ self.splitblocks( ["´" , ´"´ , "/*" , "<!--" , "#" , ";" ],
+ ["´" , ´"´ , "*/" , "-->" , "\n", "\n"]).each do |type, s|
+ case type
+ when 0, 1, 2 then res << s
+ when 3, 4, 5
+ end
+ end
+ res.join("")
+ end
+
+ def noquotes
+ self.sub(/\A[´"]/, "").sub(/[´"]\z/, "")
+ end
+
+ def to_html(eolconversion=true)
+ s = CGI.escapeHTML(self)
+
+ s.gsub!(/\"/, "\"")
+ s.gsub!(/\´/, "\´")
+
+ if eolconversion
+ s.gsub!(/\n/ , "<br>")
+ end
+
+ s
+ end
+
+ def from_html(eolconversion=true)
+ s = self
+
+ s.gsub!(/"/ , "\"")
+ s.gsub!(/´/, "\´")
+
+ s = CGI.unescapeHTML(self)
+
+ if eolconversion
+ s.gsub!(/<br>/, "\n")
+ end
+
+ s
+ end
+
+ def to_fs
+ if numeric?
+ to_f
+ else
+ to_s
+ end
+ end
+end
+
+class Array
+ def chomp!
+ self.collect!{|s| s.chomp}
+ end
+
+ def chomp
+ self.collect{|s| s.chomp}
+ end
+
+ def compress
+ self.collect{|s| s.compress}
+ end
+
+ def uncomment
+ self.join("\0").uncomment.split("\0")
+ end
+
+ def strip
+ self.collect{|s| s.strip}
+ end
+
+ def sum
+ res = 0
+ self.each do |n|
+ res += n
+ end
+ res
+ end
+
+ def product
+ res = 1
+ self.each do |n|
+ res *= n
+ end
+ res
+ end
+
+ def joinwords(sep=" ", quote=´"´)
+ self.collect do |s|
+ s = quote + s + quote if s =~ /[[:blank:]]/
+ s
+ end.join(sep)
+ end
+
+ def domino(tabellen, kolom=nil, onlymatchinglines=false)
+ links = self
+ res = []
+ res = self.dup unless onlymatchinglines
+
+ tabellen.each do |rechts|
+ tmp = []
+
+ links.each do |l|
+ if kolom.nil? or l.length == kolom
+ rechts.each do |r|
+ tmp << l + r[1..-1] if l[-1] == r[0]
+ end
+ end
+ end
+
+ links = tmp
+ res.concat(tmp)
+ end
+
+ res = res.sort.uniq
+ end
+
+ def dominoloop(tabellen)
+ lres = []
+ res = self.dup
+ kolom = 2
+
+ while lres.length != res.length do
+ lres = res.dup
+ res = res.domino(tabellen, kolom)
+
+ res.each do |line|
+ line << "*" if (line.length != line.uniq.length and line[-1] != "*")
+ end
+
+ $stderr.print "#{100*(res.length)/(lres.length)}% "
+
+ kolom += 1
+ end
+
+ $stderr.puts ""
+
+ return res
+ end
+
+ def buildtree
+ self.dominoloop([self])
+ end
+
+ def subset(fields, values, results, exact=true, emptyline=nil, joinwith=nil)
+ fields = [fields] if not fields.kind_of? Array
+ values = [values] if not values.kind_of? Array
+ results = [results] if not results.kind_of? Array
+ res = []
+
+ self.each do |l|
+ ok = true
+
+ case l.class.to_s
+ when "String"
+ c = l.splitwords
+ correction = 1
+ joinwith = " " if joinwith.nil?
+ when "Array"
+ c = l
+ correction = 0
+ end
+
+ 0.upto(c.length-1) do |n|
+ if fields.include?(n+correction)
+ v = values[fields.index(n+correction)]
+ if not emptyline.nil? and not v.downcase == emptyline.downcase
+ if exact
+ ok = false unless (v.nil? or c[n].downcase == v.downcase)
+ else
+ ok = false unless (v.nil? or c[n].downcase.include?(v.downcase))
+ end
+ end
+ end
+ end
+
+ if ok
+ res2 = []
+ results.each do |n|
+ res2 << c[n-1]
+ end
+ res2 = res2.join(joinwith) if not joinwith.nil?
+ res << res2
+ end
+ end
+
+ return res
+ end
+
+ def format(format)
+ res = []
+
+ [format.length, self.length].min.times do |n|
+ case format[n].chr
+ when "i" then res << self[n].to_i
+ when "s" then res << self[n].to_s
+ when "x" then res << self[n]
+ end
+ end
+
+ res
+ end
+
+ def to_i
+ collect{|c| c.to_i}
+ end
+
+ def to_par
+ dash = self.dup
+ alpha = self.dup
+ numeric = self.dup
+
+ dash.delete_if do |s|
+ not (s =~ /\A-/) or
+ (s =~ /\A-?[[:digit:]\.]+\z/) or
+ (s =~ /^-+$/)
+ end
+
+ alpha.delete_if do |s|
+ ((s =~ /\A-/) or
+ (s =~ /\A-?[[:digit:]\.]+\z/)) and
+ not ((s =~ /^\.+$/) or (s =~ /^-+$/))
+ end
+
+ numeric.delete_if do |s|
+ not (s =~ /\A-?[[:digit:]\.]+\z/) or
+ (s =~ /^\.+$/)
+ end
+
+ raise "Oops!" if dash.length + alpha.length + numeric.length != length
+
+ return dash, alpha, numeric
+ end
+
+ def self.file(file)
+ res = []
+
+ File.new(file).readlines.uncomment.chomp.each do |line|
+ res << line
+ end
+
+ res
+ end
+
+ def numsort
+ sort do |a, b|
+ a2 = a.to_fs
+ b2 = b.to_fs
+
+ if a2.class != b2.class
+ a2 = a
+ b2 = b
+ end
+
+ a2 <=> b2
+ end
+ end
+
+ def to_fs
+ collect{|s| s.to_fs}
+ end
+
+ def chaos
+ res = self.dup
+
+ (length^2).times do
+ a = rand(length)
+ b = rand(length)
+
+ res[a], res[b] = res[b], res[a]
+ end
+
+ res
+ end
+
+ def minmax
+ min, value, max = self
+ [min, [value, max].min].max
+ end
+end
+
+class Hash
+ def save(file, append=false)
+ org = {}
+ org = Hash.file(file) if (append and File.file?(file))
+
+ self.sort.each do |k, v|
+ org[k] = v
+ end
+
+ File.open(file, "w") do |f|
+ org.sort.each do |k, v|
+ #f.puts "´%s´=´%s´" % [k, v]
+ f.puts "%s = %s" % [k, v]
+ end
+ end
+ end
+
+ def subset(fields, values, results=nil, exact=true, emptyline=nil, joinwith=nil)
+ fields = [fields] if not fields.kind_of? Array
+ values = [values] if not values.kind_of? Array
+ results = [results] if not results.kind_of? Array
+ res = self.dup
+ res.delete_if {true}
+
+ self.each do |k, l|
+ ok = true
+
+ case l.class.to_s
+ when "String"
+ c = l.splitwords
+ correction = 1
+ joinwith = " " if joinwith.nil?
+ when "Array"
+ c = l
+ correction = 0
+ end
+
+ 0.upto(c.length-1) do |n|
+ if fields.include?(n+correction)
+ v = values[fields.index(n+correction)]
+ if emptyline.nil? or (not emptyline.nil? and not v.downcase == emptyline.downcase)
+ if exact
+ ok = false unless (v.nil? or c[n].downcase == v.downcase)
+ else
+ ok = false unless (v.nil? or c[n].downcase.include?(v.downcase))
+ end
+ end
+ end
+ end
+
+ if ok
+ res2 = []
+ if results == [nil]
+ res2 = c
+ else
+ results.each do |n|
+ res2 << c[n-correction]
+ end
+ end
+ res2 = res2.join(joinwith) if not joinwith.nil?
+ res[k] = res2
+ end
+ end
+
+ return res
+ end
+
+ def to_i
+ collect{|k, v| v.to_i}
+ end
+
+ def self.file(file)
+ res = {}
+
+ File.new(file).readlines.chomp.each do |line|
+ if not line.compress.empty?
+ k, v = line.split(/\s*=\s*/, 2)
+ res[k] = v
+ end
+ end
+# File.new(file).readlines.uncomment.chomp.each do |line|
+# if not line.compress.empty?
+# a = line.splitwords("=")
+#
+# if a.size == 3 and a[1] == "="
+# res[a[0]] = a[2]
+# else
+# puts "Error in #{file} (not ´var=\"value\"´)."
+# end
+# end
+# end
+
+ res
+ end
+end
+
+class Dir
+ def Dir.mkdirrec(dir)
+ pdir = File.dirname(dir)
+
+ if not pdir.empty? and not FileTest.directory?(pdir)
+ mkdirrec (pdir)
+ end
+
+ Dir.mkdir(dir) rescue nil
+ end
+end
+
+def id2ref(id)
+ ObjectSpace._id2ref(id)
+end
+
+def after(seconds)
+ if not seconds.nil? and not seconds.zero?
+ Thread.new do
+ sleep seconds
+ yield
+ end
+ end
+end
+
+def every(seconds)
+ if not seconds.nil? and not seconds.zero?
+ Thread.new do
+ loop do
+ sleep seconds
+ yield
+ end
+ end
+ end
+end
+
+def evtimeout(seconds)
+ if not seconds.nil? and not seconds.zero?
+ t = Thread.current
+ threads = []
+ res = nil
+
+ threads[1] = Thread.new do
+ sleep seconds
+ begin
+ threads[2].kill
+ rescue NameError
+ end
+ res = false
+ t.wakeup
+ end
+
+ threads[2] = Thread.new do
+ yield
+ begin
+ threads[1].kill
+ rescue NameError
+ end
+ res = true
+ t.wakeup
+ end
+
+ threads[1].join
+ threads[2].join
+
+ return res
+ else
+ yield
+ end
+end
+
+def evtimeoutretry(seconds)
+ ok = false
+
+ while not ok
+ evtimeout(seconds) do
+ yield
+ ok = true
+ end
+ end
+end
+
+def trap(signal)
+ Kernel::trap(signal) do
+ yield
+ end
+
+ # Seems pointless, but it´s for catching ^C under Windows...
+
+ every(1) {}
+end
+
+def linux?
+ not windows? and not cygwin?
+end
+
+def windows?
+ not (target_os.downcase =~ /32/).nil?
+end
+
+def cygwin?
+ not (target_os.downcase =~ /cyg/).nil?
+end
+
+def target_os
+ Config::CONFIG["target_os"] or ""
+end
+
+def user
+ ENV["USER"] or ENV["USERNAME"]
+end
+
+def home
+ (ENV["HOME"] or ENV["USERPROFILE"] or (File.directory?("h:/") ? "h:" : "c:")).gsub(/\\/, "/")
+end
+
+def temp
+ (ENV["TEMP"] or "/tmp").gsub(/\\/, "/")
+end
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/rwd.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/rwd.lib.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/rwd.lib.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/rwd.lib.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,1320 @@
+require "ev/xml"
+require "ev/net"
+require "md5"
+require "rbconfig"
+require "pstore"
+
+begin
+ require "win32ole"
+ require "win32/registry"
+rescue LoadError
+ $".push "win32ole.rb"
+ $".push "win32/registry.rb"
+end
+
+exit if ARGV.include?("--rwd-exit")
+
+Debug = false
+Border = 0
+RWDEmptyline = "..."
+
+rcfile = nil
+s = ENV["HOME"] ; s = s + "/.rwdrc" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and FileTest.file?(s))
+s = ENV["USERPROFILE"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and FileTest.file?(s))
+s = ENV["windir"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and FileTest.file?(s))
+
+AL = "align=´left´"
+AC = "align=´center´"
+AR = "align=´right´"
+VA = "valign=´middle´"
+
+Format = "\n<!-- %-10s %-10s -->\t"
+
+if not rcfile.nil?
+ puts "Reading #{rcfile} ..."
+
+ Hash.file(rcfile).each do |k, v|
+ ENV[k] = v
+ end
+else
+ begin
+ puts "Looking for default browser..."
+ ENV["RWDBROWSER"] = Win32::Registry::HKEY_CLASSES_ROOT.open(´htmlfile\shell\open\command´)[0]
+ rescue
+ puts "Not found."
+ end
+
+ if not ENV.include?("RWDBROWSER") and false # ???
+ s = ENV["HOME"] ; s = s + "/.rwdrc" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil?)
+ s = ENV["USERPROFILE"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil?)
+ s = ENV["windir"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil?)
+
+ if not rcfile.nil?
+ puts "Creating #{rcfile} ..."
+ puts ""
+ puts "# This is the first time you start a RubyWebDialog application."
+ puts "# I have to know your favorite browser."
+ puts "# "
+ puts "# Put the full path to your favorite browser between the quotes"
+ puts "# (\"...\") after RWDBROWSER= and remove the hash (#) at the"
+ puts "# beginning of the line."
+ puts "# "
+ puts "# Restart your application."
+ puts ""
+
+ File.open(rcfile, "a") do |f|
+ f.puts "# This is the first time you start a RubyWebDialog application."
+ f.puts "# I have to know your favorite browser."
+ f.puts "# "
+ f.puts "# Put the full path to your favorite browser between the quotes"
+ f.puts "# (\"...\") after RWDBROWSER= and remove the hash (#) at the"
+ f.puts "# beginning of the line."
+ f.puts "# "
+ f.puts "# Restart your application."
+ f.puts ""
+ f.puts "#RWDBROWSER=\"...\""
+ end
+ end
+
+ if windows?
+ system("notepad #{rcfile}")
+
+ sleep 1
+ else
+ puts "Please edit #{rcfile}."
+ end
+
+ exit
+ end
+end
+
+trap("INT") {puts "Terminating..." ; exit}
+
+$SAFE = 2
+
+class IE
+ def initialize(url)
+ @ie = WIN32OLE.new("InternetExplorer.Application")
+ @ev = WIN32OLE_EVENT.new(@ie, "DWebBrowserEvents2")
+
+ @ie.navigate(url)
+
+ @ie.menubar = false
+ @ie.toolbar = false
+ @ie.addressbar = false
+ @ie.statusbar = false
+
+ @ie.visible = true
+
+ at_exit do
+ @ie.visible = false
+ end
+
+ @ev.on_event("OnQuit") do
+ Thread.main.exit
+ end
+
+ Thread.new do
+ loop do
+ WIN32OLE_EVENT.message_loop
+ end
+ end
+ end
+end
+
+class Array
+ def rwd_options(emptyline=nil)
+ if emptyline.nil?
+ a = self
+ else
+ a = [emptyline].concat self
+ end
+
+ a.numsort.collect{|s| "<option>#{s.to_html}</option>" }.join("\n")
+ end
+
+ def rwd_method(method)
+ res = ""
+
+ self.each do |s|
+ s = s.join("/") if s.kind_of?(Array)
+ s2 = s.dup
+ s2[0..0] = s2[0..0].upcase
+ res = res + "<p align=´left´><a action=´#{method}/#{s.to_html}´>#{s2.to_html}</a></p>"
+ end
+
+ return res
+ end
+
+ def rwd_row(key=nil, value=nil)
+ res = ""
+
+ res = res + "<row valign=´top´>"
+ res = res + "<radio name=´#{key.to_html}´ value=´#{value.to_html}´/>" if not key.nil?
+ res = res + self.collect{|s| "<p align=´left´>#{s.to_html}</p>"}.join("")
+ res = res + "</row>"
+
+ return res
+ end
+
+ def rwd_headers(emptyfield=false)
+ res = ""
+
+ res = res + "<row>"
+ res = res + "<p/>" if emptyfield
+ res = res + self.collect{|s| "<p align=´left´><b>#{s.to_html}</b></p>" }.join("")
+ res = res + "</row>"
+
+ return res
+ end
+
+ def rwd_form(prefix, values, twoparts=0, options={})
+ res = []
+
+ res << "<table>"
+ self.each_index do |n|
+ name = "#{prefix.to_html}#{self[n].downcase.to_html}"
+
+ res << "<row>"
+ res << "<p align=´right´>"
+ res << "#{self[n].to_html}:"
+ res << "</p>"
+
+ if options.keys.include?(self[n])
+ res << "<select name=´#{name}´>"
+ res << options[self[n]].rwd_options(RWDEmptyline)
+ res << "</select>"
+ else
+ s = ""
+
+ s << "<text name=´#{name}´"
+ s << " value=´#{values[n].to_html}´" if n < values.length
+ s << "/>"
+
+ res << s
+ end
+
+ res << "</row>"
+
+ if twoparts > 0 and n == twoparts-1
+ res << "<row><empty/></row>"
+ end
+ end
+ res << "</table>"
+
+ return res.join("\n")
+ end
+end
+
+class Hash
+ def rwd_table(field, joinwith=@sep, headers=nil)
+ res = []
+
+ res << "<table>"
+ res << headers.rwd_headers(true) if not headers.nil?
+ self.keys.numsort.each do |key|
+ key2 = key
+ value2 = self[key]
+
+ key2 = key2.join(joinwith) if key2.kind_of?(Array)
+ value2 = [value2] if value2.kind_of?(String)
+
+ res << value2.rwd_row(field, key2)
+ end
+ res << "</table>"
+
+ res.join("\n")
+ end
+end
+
+class EVTable
+ def rwd_table(key, joinwith)
+ super(key, joinwith, @headers)
+ end
+
+ def rwd_form(prefix="", key=nil, twoparts=false)
+ values = self[key] if not key.nil?
+ values = [] if values.nil?
+ options = {}
+
+ if File.file?(oldlocation("constraints.csv"))
+ table = File.basename(@file).gsub(/\.csv$/, "")
+
+ CSVFile.new(oldlocation("constraints.csv")).subset(["Table", "Constraint"], [table, "key"], ["Column", "Value"]).values.each do |column, table2|
+ options[column] = CSVFile.new(oldlocation("#{table2}.csv")).keys.collect{|a| a.join("\t")}
+ end
+ end
+
+ @headers.rwd_form(prefix, values, twoparts ? @key : 0, options)
+ end
+
+ def rwd_metadata
+ res = []
+
+ res << "<table>"
+ res << "<row>"
+ res << " <empty/>"
+ res << " <text name=´header_new´ value=´´/>"
+ res << "</row>"
+ @headers.each_index do |n|
+ res << "<row>"
+ res << " <text name=´header_#{n}_old´ value=´#{@headers[n]}´/>"
+ res << " <text name=´header_#{n}_new´ value=´´/>"
+ res << "</row>"
+ end
+ res << "</table>"
+
+ return res.join("\n")
+ end
+end
+
+class OpenTag
+ def prechildren(res, before, after, vars, switches, help, firstaction, tabs, tab)
+ bef = before[-1]
+ res.concat Format % ["Before", @subtype] if (Debug and not bef.nil?)
+ res.concat bef if not bef.nil?
+
+ res.concat Format % ["Pre", @subtype] if Debug
+
+ align = AC
+ align = "align=´#{@args["align"]}´" if @args.include?("align")
+
+ valign = VA
+ valign = "valign=´#{@args["valign"]}´" if @args.include?("valign")
+
+ value = ""
+ value = vars[@args["name"]] if vars.include?(@args["name"])
+ value = @args["value"] if @args.include?("value")
+
+ case @subtype
+ when "application"
+ when "window", "helpwindow"
+ args = @args.deep_dup
+
+ args["nohelpbutton"] = (not help)
+
+ res.concat(template(RWD_HTML1, args))
+ when "p" then res.concat "<p #{align}>"
+ when "pre" then res.concat "<pre>"
+ when "big" then res.concat "<p #{align}><big>"
+ when "small" then res.concat "<p #{align}><small>"
+ when "list" then res.concat "<ul #{align}>"
+ when "item" then res.concat "<li #{align}>"
+ when "empty" then res.concat "<p><br>"
+ when "image" then res.concat "<img src=´#{@args["src"]}´>"
+ when "br" then res.concat "<br>"
+ when "hr" then res.concat "<hr>"
+ when "b" then res.concat "<b>"
+ when "i" then res.concat "<i>"
+ when "a"
+ if @args.include?("href")
+ res.concat "<a href=´#{@args["href"]}´ target=´#{@args["target"] or "new"}´>"
+ else
+ res.concat "<a href=´javascript:document.bodyform.rwd_action.value=\"#{@args["action"]}\";document.bodyform.submit();´>"
+ end
+ when "vertical" then res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>"
+ when "horizontal" then res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´><tr #{align} #{valign}>"
+ when "table" then res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>"
+ when "row" then res.concat "<tr #{align} #{valign}>"
+ when "hidden" then res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´hidden´>"
+ when "text" then res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´text´>"
+ when "textarea" then res.concat "<p #{align}><textarea name=´#{@args["name"]}´>#{value}</textarea>"
+ when "password" then res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´password´>"
+ when "checkbox"
+ if vars[@args["name"]] == "on"
+ switches[@args["name"]] = true
+ res.concat "<p #{align}><input name=´#{@args["name"]}´ checked=´on´ type=´checkbox´>"
+ else
+ switches[@args["name"]] = false
+ res.concat "<p #{align}><input name=´#{@args["name"]}´ type=´checkbox´>"
+ end
+ when "radio"
+ if vars[@args["name"]] == value
+ res.concat "<p #{align}><input name=´#{@args["name"]}´ checked=´on´ value=´#{value}´ type=´radio´>"
+ else
+ res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´radio´>"
+ end
+ when "select"
+ res.concat "<select #{align} name=´#{@args["name"]}´ width=´#{@args["width"]}´>"
+ name = @args["name"]
+ $select = vars[name]
+ when "option"
+ if $select == @children[0].text
+ res.concat "<option selected=´true´>"
+ else
+ res.concat "<option>"
+ end
+ when "button"
+ res.concat "<input type=´submit´ value=´#{@args["caption"]}´ onclick=´document.bodyform.rwd_action.value=\"#{@args["action"]}\";´>"
+ firstaction << @args["action"] if (firstaction.empty? and @args.include?("action"))
+ when "back"
+ res.concat "<input type=´submit´ value=´Back´ onclick=´document.bodyform.rwd_action.value=\"rwd_back\";´>"
+ firstaction << "rwd_back" if firstaction.empty?
+ when "help"
+ res.concat "<input type=´submit´ value=´Help´ onclick=´document.bodyform.rwd_action.value=\"rwd_help\";´>"
+ firstaction << "rwd_help" if firstaction.empty?
+ when "quit"
+ res.concat "<input type=´submit´ value=´Quit´ onclick=´document.bodyform.rwd_action.value=\"rwd_quit\";´>"
+ firstaction << "rwd_quit" if firstaction.empty?
+ when "close"
+ res.concat "<input type=´submit´ value=´Close´ onclick=´window.close();´>"
+ firstaction << "rwd_quit" if firstaction.empty?
+ when "reset"
+ res.concat "<input type=´reset´ value=´Reset´>"
+ firstaction << "rwd_quit" if firstaction.empty?
+ when "closewindow"
+ #res.concat "<script type=´text/javascript´>\n"
+ #res.concat "<!--\n"
+ #res.concat " window.close();\n"
+ #res.concat "//-->\n"
+ #res.concat "</script>"
+ when "tabs"
+ res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>"
+ res.concat " <tr #{AC}>"
+ res.concat " <td #{AC}>"
+ res.concat " <table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>"
+ res.concat " <tr #{AC}>"
+ tabs.each do |obj|
+ caption = obj.args["caption"]
+ if caption == tab
+ res.concat "<td #{AC}><div class=´box´><tt><b> #{caption} </b></tt></div></td>"
+ else
+ res.concat "<td #{AC}><div class=´box´><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_tab_#{caption}\";document.bodyform.submit();´><tt> #{caption} </tt></a></div></td>"
+ end
+ end
+ res.concat " </tr>"
+ res.concat " </table>"
+ res.concat " </td>"
+ res.concat " </tr>"
+ when "tab"
+ res.concat "<tr #{align} #{valign}><td #{align}><div class=´box2´>"
+ else
+ puts "<#{@subtype}>"
+ res.concat "<#{@subtype}>"
+ end
+
+ bef = nil
+ aft = nil
+
+ case @subtype
+ when "vertical", "window", "helpwindow"
+ res.concat Format % ["AftPre", @subtype] if Debug
+ if @args.include?("spacing")
+ s = "<tr><td> </td></tr>" * (@args["spacing"].to_i)
+ else
+ s = ""
+ end
+ bef = "#{s}<tr #{align} #{valign}><td #{align}>"
+ aft = "</td></tr>"
+ when "horizontal", "row"
+ res.concat Format % ["AftPre", @subtype] if Debug
+ bef = "<td #{align}>"
+ aft = "</td>"
+ end
+
+ before.push(bef)
+ after.push(aft)
+ end
+
+ def postchildren(res, before, after, vars, switches, help, firstaction, tabs, tab)
+ case @subtype
+ when "vertical", "window", "helpwindow"
+ res.concat Format % ["BefPost", @subtype] if Debug
+ if @args.include?("spacing")
+ res.concat "<tr><td> </td></tr>" * (@args["spacing"].to_i)
+ end
+ when "horizontal", "row"
+ res.concat Format % ["BefPost", @subtype] if Debug
+ end
+
+ res.concat Format % ["Post", @subtype] if Debug
+
+ case @subtype
+ when "application"
+ when "window", "helpwindow"
+ args = @args.deep_dup
+
+ args["nohelpbutton"] = (not help)
+
+ res.concat(template(RWD_HTML2, args))
+ when "p" then res.concat "</p>"
+ when "pre" then res.concat "</pre>"
+ when "big" then res.concat "</big></p>"
+ when "small" then res.concat "</small></p>"
+ when "list" then res.concat "</ul>"
+ when "item" then res.concat "</li>"
+ when "empty" then res.concat "</p>"
+ when "image" then res.concat ""
+ when "br" then res.concat ""
+ when "hr" then res.concat ""
+ when "b" then res.concat "</b>"
+ when "i" then res.concat "</i>"
+ when "a" then res.concat "</a>"
+ when "vertical" then res.concat "</table>"
+ when "horizontal" then res.concat "</tr></table>"
+ when "table" then res.concat "</table>"
+ when "row" then res.concat "</tr>"
+ when "hidden" then res.concat "</p>"
+ when "text" then res.concat "</p>"
+ when "textarea" then res.concat "</p>"
+ when "password" then res.concat "</p>"
+ when "checkbox" then res.concat "</p>"
+ when "radio" then res.concat "</p>"
+ when "select"
+ res.concat "</select>"
+ $select = nil
+ when "option" then res.concat "</option>"
+ when "button" then res.concat ""
+ when "back" then res.concat ""
+ when "help" then res.concat ""
+ when "quit" then res.concat ""
+ when "close" then res.concat ""
+ when "reset" then res.concat ""
+ when "closewindow" then res.concat ""
+ when "tabs" then res.concat "</table>"
+ when "tab" then res.concat "</div></td></tr>"
+ else
+ puts "</#{@subtype}>"
+ res.concat "</#{@subtype}>"
+ end
+
+ before.pop
+ after.pop
+
+ aft = after[-1]
+ res.concat Format % ["After", @subtype] if (Debug and not aft.nil?)
+ res.concat aft if not aft.nil?
+ end
+
+ def template(html, vars)
+ res = []
+
+ a = {}
+
+ vars.each do |k, v|
+ a[k.upcase] = v
+ end
+
+ a["LOGO"] = "" unless ((not vars["logo"].nil?) and FileTest.file?(vars["logo"]))
+
+ a["HELPBUTTON"] = (not (vars["nohelpbutton"]))
+ a["BACKBUTTONS"] = (not (vars["nobackbuttons"]))
+ a["BACKBUTTONS"] = (not (vars["nobackbuttons"]))
+ a["CLOSEBUTTON"] = (not (vars["noclosebutton"]))
+
+ html.split(/\r*\n/).each do |line|
+ if line =~ /%[A-Z]+%/
+ a.each do |k, v|
+ v = false if (v.kind_of?(String) and v.empty?)
+
+ if line.include?("%#{k}%")
+ line.gsub!("%#{k}%", "#{v}") if v
+ end
+ end
+
+ line = "<!-- #{line.scan(/%[A-Z]+%/).join(" ")} -->" if line =~ /%[A-Z]+%/
+ end
+
+ res << line
+ end
+
+ res.join("\n")
+ end
+end
+
+class Text
+ def prechildren(res, before, after, vars, switches, help, firstaction, tabs, tab)
+ if not @text.scan(/[^ \t\r\n]/).empty?
+ res.concat Format % ["Text", ""] if Debug
+ res.concat "#{@text}"
+ end
+ end
+end
+
+class RWDTree < XML
+end
+
+class RWDWindow
+ @@windows = {} # Kind of caching.
+ @@helpwindows = {} # Kind of caching.
+
+ def initialize(rwd, window=nil)
+ rwd = rwd.join("\n") if rwd.kind_of?(Array)
+
+ if @@windows[rwd].nil?
+ @@windows[rwd] = {}
+ @@helpwindows[rwd] = {}
+
+ tree = XML.new(rwd)
+
+ tree.parse(OpenTag, "window") do |type, obj|
+ @@windows[rwd][obj.args["name"]] = obj.to_h
+ end
+
+ tree.parse(OpenTag, "helpwindow") do |type, obj|
+ @@helpwindows[rwd][obj.args["name"]] = obj.to_h
+ end
+ end
+
+ @rwd = (@@windows[rwd][window] or "").dup
+ @helprwd = (@@helpwindows[rwd][window] or "").dup
+ end
+
+ def render(vars=Hash.new, switches=Hash.new, help=false, tab="")
+ vars2 = Hash.new
+ firstaction = ""
+ html = ""
+
+ vars.each do |key, value|
+ if not key.empty?
+ if value.respond_to? "to_s"
+ @rwd.gsub!(/%%#{key}%%/, value.to_s)
+ @rwd.gsub!(/%#{key}%/, value.to_s.to_html)
+
+ @helprwd.gsub!(/%%#{key}%%/, value.to_s)
+ @helprwd.gsub!(/%#{key}%/, value.to_s.to_html)
+
+ vars2[key] = value.to_s.to_html
+ end
+ end
+ end
+
+ windowobject = RWDTree.new(@rwd).children.dup.delete_if{|obj| obj.subtype != "window"}[0]
+ helpobject = RWDTree.new(@helprwd).children.dup.delete_if{|obj| obj.subtype != "helpwindow"}[0]
+
+ tabsobj = windowobject.children.dup.delete_if{|obj| obj.subtype != "tabs"}[0]
+
+ if not tabsobj.nil?
+ tabs = tabsobj.children.dup.delete_if{|obj| (not obj.kind_of?(OpenTag)) or (obj.subtype != "tab")}
+
+ if tab.empty?
+ tab = tabs[0].args["caption"]
+ end
+
+ tabsobj.children.delete_if{|obj| (obj.kind_of?(OpenTag)) and (obj.subtype == "tab") and obj.args["caption"] != tab}
+ end
+
+ if help
+ helpobject.parsetree("prechildren", "postchildren", html, [""], [""], vars2, switches, false, firstaction, tabs, tab)
+ else
+ windowobject.parsetree("prechildren", "postchildren", html, [""], [""], vars2, switches, (not @helprwd.empty?), firstaction, tabs, tab)
+ end
+
+ html.gsub!(/%%*[[:alnum:]_\-]+%%*/, "") if not Debug
+ html.gsub!(/%%/, "%")
+ html.gsub!(/\n\n*/, "\n")
+
+ if firstaction.empty?
+ focus = ""
+ else
+ focus = "document.bodyform.elements[0].focus();"
+ end
+
+ html.gsub!(/\$RWD_FIRSTACTION\$/ , firstaction)
+ html.gsub!(/\$RWD_FOCUS\$/ , focus)
+
+ html
+ end
+end
+
+class RWDMessage < RWDWindow
+ def initialize(msg)
+ super("<window title=´RWD Message´ nobackbuttons><vertical><p><b>Message:</b> #{msg}</p><back/></vertical></window>")
+ end
+end
+
+class RWDError < RWDWindow
+ def initialize(msg)
+ super("<window title=´RWD Error´ nobackbuttons><vertical><p><b>Error:</b> #{msg}</p><back/></vertical></window>")
+ end
+end
+
+class RWDDone < RWDWindow
+ def initialize(exitbrowser)
+ super("<window title=´RWD Message´ nobackbuttons noclosebutton><p>Done.</p><horizontal><close/>#{exitbrowser ? "" : "<button caption=´Login´/>"}</horizontal>#{exitbrowser ? "<closewindow/>" : ""}</window>")
+ end
+end
+
+class RWDialog
+ def initialize(xml)
+ @rwd_xml = xml
+ @rwd_exitbrowser = false
+ @rwd_history = []
+ @rwd_clone_vars = ["@rwd_history"]
+ @rwd_ignore_vars = ["@rwd_server"]
+ end
+
+ def self.file(rwdfile, *args)
+ new(File.new(rwdfile).readlines, *args)
+ end
+
+ def serve(port=1234, auth=nil, realm=self.class.to_s)
+ raise "RWD is not initialized." if @rwd_xml.nil?
+
+ @rwd_server = RWDServer.new(self, port, auth, realm)
+ end
+
+ def render(res, path, post, sessionid)
+
+ # Initialize some vars.
+
+ vars = Hash.new if vars.nil?
+ @rwd_switches = Hash.new if @rwd_switches.nil?
+
+ done = false
+ help = false
+ back = false
+ tab = ""
+ @rwd_msg = nil
+
+ # Switches are used for checkboxes.
+
+ @rwd_switches.each do |key, value|
+ vars[key] = "off"
+ end
+
+ @rwd_switches = Hash.new
+
+ # Copy the vars from the window to vars. vars wil later on be copied to instance variables.
+
+ post.sort.each do |key, value|
+ puts "Post: #{key} -> #{value.from_html.inspect}" if Debug
+
+ vars[key] = value.from_html
+ end
+
+ # Stack handling for rwd_action and rwd_window.
+
+ @rwd_action = vars["rwd_action"]
+ @rwd_action, @rwd_args = @rwd_action.split(/\//, 2) unless @rwd_action.nil?
+
+ if @rwd_action =~ /^rwd_tab_/
+ tab = @rwd_action.sub(/^rwd_tab_/, "")
+ else
+ case @rwd_action
+ when "rwd_back"
+ @rwd_history.pop
+ @rwd_action = (@rwd_history[-1] or [nil, nil])[0]
+ @rwd_window = (@rwd_history[-1] or [nil, nil])[1]
+ back = true
+ when "rwd_help"
+ help = true
+ when "rwd_main"
+ @rwd_window = "main"
+ @rwd_action = "main"
+ @rwd_history = []
+ when "rwd_quit"
+ done = true
+ end
+
+ # History stuff
+
+ @rwd_history = @rwd_history[-100..-1] if @rwd_history.length >= 100
+ @rwd_action = "main" if @rwd_action.nil?
+ @rwd_action = "main" if @rwd_action.empty?
+ @rwd_args = [] if @rwd_args.nil?
+ @rwd_window = "main" if @rwd_window.nil?
+
+ vars["rwd_action"] = @rwd_action
+ vars["rwd_window"] = @rwd_window
+
+ # Copy vars from window to instance.
+
+ vars.each do |k, v|
+ instance_eval "@#{k} = vars[´#{k}´]" if ((not k.empty?) and k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}"))
+ end
+
+ # Callback.
+
+ if not back
+ begin
+ puts "Method: #{@rwd_action}(#{@rwdargs.join(", ")})" if Debug
+ method(@rwd_action).call(*@rwd_args)
+ rescue NameError
+ end
+
+ # History stuff
+
+ @rwd_history = [["main", "main"]] if @rwd_action == "main"
+ @rwd_history = [["main", "main"]] if @rwd_history.empty?
+ @rwd_history.push [@rwd_action, @rwd_window] if (@rwd_history[-1] != [@rwd_action, @rwd_window] or not @rwd_msg.nil?)
+ end
+ end
+
+ # Copy vars from instance to window.
+
+ instance_variables.each do |k|
+ k.sub!(/^@/, "")
+ instance_eval "vars[´#{k}´] = @#{k}.to_s" if (k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}"))
+ end
+
+ # just ignore.
+
+ vars.sort.each do |key, value|
+ puts "Pre: #{key} -> #{value.inspect}" if Debug
+ end
+
+ # Answer to browser.
+
+ if done
+ res << RWDDone.new(@rwd_exitbrowser).render
+ else
+ if not @rwd_msg.nil?
+ res << RWDMessage.new(@rwd_msg).render if @rwd_msgtype == "message"
+ res << RWDError.new(@rwd_msg).render if @rwd_msgtype == "error"
+ else
+ puts "Window: #{@rwd_window}" if Debug
+ res << RWDWindow.new(@rwd_xml, @rwd_window).render(vars, @rwd_switches, help, tab)
+ end
+ end
+
+ return done
+ end
+
+ def samewindow?
+ @rwd_history[-1][1] == @rwd_window
+ end
+
+ def message(msg)
+ @rwd_msg = msg
+ @rwd_msgtype = "message"
+ end
+
+ def error(msg)
+ @rwd_msg = msg
+ @rwd_msgtype = "error"
+ end
+
+ def clone
+ @rwd_history = []
+
+ @rwd_clone_vars.each do |var|
+ instance_eval "#{var} = #{var}.clone"
+ end
+
+ super
+ end
+
+ def exitbrowser
+ @rwd_exitbrowser = true
+ end
+end
+
+class RWDLogin < RWDialog
+ def initialize(realm)
+ super("<window name=´main´ title=´RWD Login for #{realm}´ nobackbuttons noclosebutton><table><row><p align=´right´>Username:</p><text name=´rwd_a´/></row><row><p align=´right´>Password:</p><password name=´rwd_b´/></row></table><button caption=´Login´/></window>")
+ end
+end
+
+class RWDTimeOut < RWDialog
+ def initialize
+ super("<window name=´main´ title=´RWD Error´ nobackbuttons noclosebutton><p><b>Error:</b> Session has expired.</p><button caption=´New session´/></window>")
+ end
+end
+
+class SessionCleanup
+ def initialize(sessions, interval, timeout)
+ every(interval) do
+ sessions.delete_if do |id, session|
+ time = Time.now.to_i - session.lastaccess.to_i
+
+ puts "Session %s deleted" % id if time > timeout
+
+ time > timeout
+ end
+ end
+ end
+end
+
+class Sessions
+ def initialize(rack, cleanup)
+ @rack = rack.to_s
+ @cleanup = SessionCleanup.new(self, 3600, 24*3600) if cleanup
+ @sessions = {}
+ #@store = PStore.new("#{temp}/store.#{@rack}.#{user}")
+
+ #@store.transaction do
+ #@store[@rack] = {} if not @store.root?(@rack)
+ #@sessions = @store[@rack]
+ #end
+
+ #at_exit do
+ #@store.transaction do
+ #@store[@rack] = @sessions
+ #end
+ #end
+ end
+
+ def [](sessionid)
+ @sessions[sessionid]
+ end
+
+ def []=(sessionid, value)
+ @sessions[sessionid] = value
+ end
+
+ def delete(sessionid)
+ @sessions.delete(sessionid)
+ end
+
+ def delete_if(&block)
+ @sessions.delete_if{|k, v| block.call(k, v)}
+ end
+end
+
+class Session < Hash
+ attr_reader :sessionid
+ attr_reader :lastaccess
+ attr_reader :authenticated
+ attr_writer :authenticated
+
+ def initialize(sessionid=nil)
+ @sessionid = sessionid
+ @lastaccess = Time.now
+ @authenticated = false
+ end
+
+ def touch
+ @lastaccess = Time.now
+ end
+end
+
+class RWDSession < Session
+ def render(res, path, post)
+ done = self["object"].render(res, path, post, @sessionid)
+
+ if done
+ res.gsub!(/\$RWD_SESSION\$/, "")
+ else
+ res.gsub!(/\$RWD_SESSION\$/, "#{@sessionid}")
+ end
+
+ done
+ end
+end
+
+class RWDServer
+ def initialize(obj, port, auth, realm)
+ @object = obj
+ @localbrowsing = false
+ @browserstarted = false
+ @sessions = Sessions.new(obj.class, (not auth.nil?))
+
+ if auth.nil?
+ @localbrowsing = true
+
+ if ENV.include?("RWDBROWSER")
+ @browserstarted = true
+ @object.exitbrowser
+
+ # Start browser.
+
+ @browserthread = Thread.new do
+ puts "Starting the browser..."
+
+ #if ENV["RWDBROWSER"].downcase =~ /iexplore/
+ #@ie = IE.new("http://localhost:#{port}/")
+ #else
+ if windows?
+ system("#{ENV["RWDBROWSER"]} \"http://localhost:#{port}/\"")
+ elsif cygwin?
+ system("#{ENV["RWDBROWSER"].gsub(/\\/, "/").gsub(/ /, "\ ")} \"http://localhost:#{port}/\"")
+ else
+ system("#{ENV["RWDBROWSER"]} \"http://localhost:#{port}/\"")
+ end
+ #end
+
+ puts "The browser has terminated."
+ end
+ end
+ end
+
+ # Start server.
+
+ catch :exit do
+ HTTPServer.serve(port, (not auth.nil?)) do |req, resp|
+ vars = req.vars.dup
+
+ if auth.kind_of? String
+ file = "#{home}/#{auth}"
+ auths = {}
+ auths = Hash.file(file) if FileTest.file?(file)
+ else
+ auths = auth
+ end
+
+ oldsessionid = vars["rwd_session"]
+
+ # Retrieve session.
+
+ session = @sessions[oldsessionid]
+
+ # Eventually create new session.
+
+ if session.nil?
+ if auth.nil?
+ session = RWDSession.new(MD5.new(req.peeraddr[3].to_s + @object.inspect.to_s).to_s)
+ session["object"] = @object
+ else
+ session = RWDSession.new(MD5.new(Time.new.to_s + req.peeraddr[3].to_s + @object.inspect.to_s).to_s)
+ session["object"] = @object.clone
+ end
+
+ if oldsessionid.nil? or oldsessionid.empty?
+ if not auth.nil? and not session.authenticated
+
+ # Check authentication
+
+ us = vars["rwd_a"]
+ pa = vars["rwd_b"]
+
+ if us.nil? or pa.nil? or auths[us] != pa
+ session = RWDSession.new
+ session["object"] = RWDLogin.new(realm)
+ else
+ session.authenticated = true
+ @sessions[session.sessionid] = session
+ end
+ else
+ @sessions[session.sessionid] = session
+ end
+ else
+ session = RWDSession.new
+ session["object"] = RWDTimeOut.new
+ end
+
+ vars = {}
+ end
+
+ # Avoid timeout.
+
+ session.touch
+
+ if req.request.path == "/"
+
+ # Serve methods/callbacks.
+
+ # Build new page.
+
+ res = ""
+
+ done = session.render(res, req.request.path, vars)
+
+ begin
+ resp["Content-Type"] = "text/html"
+
+ resp << res
+ rescue
+ puts "Sending response to browser failed."
+
+ @sessions.delete(session.sessionid)
+ end
+
+ # Eventually delete this session.
+
+ if done
+ @sessions.delete(session.sessionid)
+
+ if @localbrowsing
+ resp.flush
+
+ if @browserstarted and @browserthread.alive?
+ puts "Waiting for the browser to terminate..."
+
+ @browserthread.join
+ end
+
+ throw :exit
+ end
+ end
+
+ else
+
+ # Serve files.
+
+ if req.request.path == "/pixel.gif"
+ resp << RWD_Pixel
+ else
+ if (FileTest.file?(req.request.path.sub(/^\/*/, "")))
+ resp << File.new(req.request.path.sub(/^\/*/, ""), "rb").read rescue nil
+ else
+ resp.response = "HTTP/1.0 404 NOT FOUND"
+ end
+ end
+
+ end
+ end
+ end
+ end
+end
+
+RWD_HTML = "
+<!-- Generated by RubyWebDialog. -->
+<!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
+<html>
+ <head>
+ <title>%TITLE%</title>
+
+ <meta http-equiv=´Content-Type´ content=´text/html; charset=ISO-8859-15´>
+ <meta http-equiv=´Content-Style-Type´ content=´text/css´>
+
+ <link rel=´shortcut icon´ href=´%LOGO%´>
+
+ <style type=´text/css´>
+ <!--
+ a { text-decoration : none }
+ div.box { border : thin solid #AAAAAA }
+ div.box2 { border-top : thin solid #AAAAAA }
+ //-->
+ </style>
+
+ <script type=´text/javascript´>
+ <!--
+ function BodyGo() {
+ $RWD_FOCUS$
+ }
+ //-->
+ </script>
+ </head>
+
+ <body onload=´BodyGo()´ link=´#000000´ vlink=´#000000´ alink=´#000000´>
+ <table align=´center´ border=´0´ cellspacing=´0´ cellpadding=´0´ width=´100%´ height=´100%´>
+ <tr align=´center´ valign=´middle´>
+ <td align=´center´>
+
+ <table align=´center´ border=´0´ cellspacing=´0´ cellpadding=´0´>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+
+ <td align=´center´>
+
+ <table align=´center´ border=´0´ cellspacing=´0´ cellpadding=´0´>
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´#444488´>
+
+ <table align=´left´ border=´0´ cellspacing=´1´ cellpadding=´0´>
+ <tr align=´center´>
+ <td align=´border´><img src=´%LOGO%´ width=´14´ height=´14´></td>
+ <td align=´center´><b><small><font color=´#FFFFFF´> %TITLE% </font></small></b></td>
+ </tr>
+ </table>
+
+ <table align=´right´ border=´0´ cellspacing=´1´ cellpadding=´0´>
+ <tr align=´center´>
+ <!-- %HELPBUTTON% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();´> ? </a></small></b></td>
+ <!-- %BACKBUTTONS% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();´> << </a></small></b></td>
+ <!-- %BACKBUTTONS% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();´> < </a></small></b></td>
+ <!-- %CLOSEBUTTON% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();´> X </a></small></b></td>
+ </tr>
+ </table>
+
+ </td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´#CCCCCC´>
+ <form name=´bodyform´ action=´/´ method=´post´>
+
+ <table align=´center´ border=´0´ cellspacing=´3´ cellpadding=´0´>
+
+ %BODY%
+
+ </table>
+
+ <input name=´rwd_action´ value=´$RWD_FIRSTACTION$´ type=´hidden´>
+ <input name=´rwd_session´ value=´$RWD_SESSION$´ type=´hidden´>
+ </form>
+ </td>
+ </tr>
+ </table>
+
+ </td>
+
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ <tr align=´center´>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td>
+ </tr>
+
+ </table>
+
+ </td>
+ </tr>
+ </table>
+ </body>
+</html>
+"
+
+RWD_Pixel = "
+R0lGODlhAQABAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoK
+CgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZ
+GRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygo
+KCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3
+Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZG
+RkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV
+VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2Rk
+ZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNz
+c3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKC
+goODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGR
+kZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6Cg
+oKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v
+r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+
+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3N
+zc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc
+3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr
+6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6
++vv7+/z8/P39/f7+/v///yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQB
+CgD/ACwAAAAAAQABAAAIBAD/BQQAOw==
+".unpack("m").shift
+
+RWD_HTML1, RWD_HTML2 = RWD_HTML.split(/^\s*%BODY%\s*\r*$/)
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/sgml.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/sgml.lib.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/sgml.lib.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/sgml.lib.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,234 @@
+require "ev/tree"
+
+class SGMLObject < TreeObject
+ def to_s
+ res = ""
+
+ parsetree("prechildren_to_s", "postchildren_to_s", res)
+
+ res
+ end
+
+ def to_h
+ res = ""
+
+ parsetree("prechildren_to_sgml", "postchildren_to_sgml", res)
+
+ res
+ end
+end
+
+class Text < SGMLObject
+ def initialize(text)
+ super()
+ @text = text
+ end
+
+ def prechildren_to_s(res)
+ res << "#{@text}"
+ end
+
+ def prechildren_to_sgml(res)
+ res << "#{@text}"
+ end
+end
+
+class Comment < SGMLObject
+ def initialize(text)
+ super()
+ @text = text
+ end
+
+ def prechildren_to_sgml(res)
+ res << "#{@text}"
+ end
+end
+
+class Special < SGMLObject
+ def initialize(text)
+ super()
+ @text = text
+ end
+
+ def prechildren_to_sgml(res)
+ res << "#{@text}"
+ end
+end
+
+class Instruction < SGMLObject
+ def initialize(text)
+ super()
+ @text = text
+ end
+
+ def prechildren_to_sgml(res)
+ res << "#{@text}"
+ end
+end
+
+class Tag < SGMLObject
+ attr_reader :args
+ attr_writer :args
+
+ def initialize(subtype, args={})
+ super(subtype)
+ @args = args
+ end
+end
+
+class OpenTag < Tag
+ def initialize(*args)
+ super
+ @upordown = Down
+ end
+
+ def prechildren_to_sgml(res)
+ a = [@subtype]
+
+ @args.each do |k, v|
+ if not v.include?("´")
+ a << "#{k}=´#{v}´"
+ else
+ if not v.include?(´"´)
+ a << "#{k}=\"#{v}\""
+ else
+ a << "#{k}=´#{v.gsub(/\´/, ´"´)}´"
+ end
+ end
+ end
+
+ res << "<#{a.join(" ")}>"
+ end
+
+ def postchildren_to_sgml(res)
+ res << "</#{@subtype}>" if @closed
+ end
+end
+
+class CloseTag < Tag
+ def initialize(*args)
+ super
+ @upordown = Dummy
+ end
+end
+
+class SGML < Tree
+ def initialize(*args)
+ @tagcache = {}
+
+ super
+ end
+
+ def buildobjects(string)
+ @objects = []
+
+ string.splitblocks(["<!--", "<!", "<?", "<"], ["-->", ">", "?>", ">"]).each do |type, s|
+ case type
+ when 0 then @objects << Text.new(s)
+ when 1 then @objects << Comment.new(s)
+ when 2 then @objects << Special.new(s)
+ when 3 then @objects << Instruction.new(s)
+ when 4
+
+ tag, args, open, close = verwerktag1(s)
+
+ @objects << OpenTag.new(tag.dup, args.dup) if open
+ @objects << CloseTag.new(tag.dup, args.dup) if close
+ end
+ end
+ end
+
+ def verwerktag1(string)
+ res = nil
+
+ if @tagcache.include? string
+ res = @tagcache[string]
+
+ else
+ res = verwerktag2(string)
+
+ @tagcache[string] = res
+ end
+
+ return res
+ end
+
+ def verwerktag2(string)
+ a = []
+
+ string.splitblocks(["´", ´"´], ["´", ´"´]).collect do |type, s|
+ case type
+ when 0
+ if self.class.to_s == "HTML"
+ s.splitwords(["<", ">"]).each do |w|
+ d = w.split("=", 2)
+
+ if d.length == 1
+ a << d[0]
+ else
+ a << d[0] if not d[0].nil? and not d[0].empty?
+ a << "="
+ a << d[1] if not d[1].nil? and not d[1].empty?
+ end
+ end
+ else
+ a.concat s.splitwords(["<", "/", "=", ">"])
+ end
+ when 1, 2 then a << s
+ end
+ end
+
+ a = a[1..-2]
+ open = false
+ close = false
+
+ if not a.nil?
+ a = a[0].splitwords("/") + a[1..-1]
+
+ if a[0] == "/"
+ close = true
+ a.shift
+ else
+ open = true
+ end
+
+ if a[-1] == "/"
+ close = true
+ a.pop
+ end
+
+ tag = a.shift.downcase
+ args = {}
+
+ while not a.length.zero?
+ if a.length >= 3 and a[1] == "="
+ key = a.shift.downcase
+ dummy = a.shift
+ value = a.shift.noquotes
+ args[key] = value
+ else
+ key = a.shift.downcase
+ args[key] = ""
+ end
+ end
+ end
+
+ return [tag, args, open, close]
+ end
+
+ def to_s
+ res = ""
+
+ parsetree("prechildren_to_s", "postchildren_to_s", res)
+
+ res
+ end
+
+ def to_h
+ res = ""
+
+ parsetree("prechildren_to_sgml", "postchildren_to_sgml", res)
+
+ res
+ end
+end
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/tree.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/tree.lib.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/tree.lib.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/tree.lib.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,316 @@
+require "ev/ruby"
+require "ev/net"
+require "md5"
+require "thread"
+
+Same = 0
+Down = 1
+Up = 2
+Dummy = 3
+
+module TextArray
+ def textarray
+ @children.collect do |obj|
+ [obj.text] << obj.textarray
+ end.flatten.compact
+ end
+end
+
+
+module ParseTree
+ def parsetree(premethod="prechildren", postmethod="postchildren", *args)
+ if @visible
+ method(premethod).call(*args) if respond_to?(premethod)
+
+ @children.each do |obj|
+ obj.parsetree(premethod, postmethod, *args)
+ end
+
+ method(postmethod).call(*args) if respond_to?(postmethod)
+ end
+ end
+
+ #def parsetree(premethod="prechildren", postmethod="postchildren", *args)
+ # stack = [self]
+ # done = []
+ #
+ # while not stack.empty?
+ # obj = stack.pop
+ #
+ # if not done.include?(obj)
+ # obj.method(premethod).call(*args) if obj.respond_to?(premethod)
+ #
+ # stack.push(obj)
+ # done.push(obj)
+ #
+ # stack.concat obj.children.reverse
+ # #obj.children.reverse.each do |cobj|
+ # #stack.push(cobj)
+ # #end
+ # else
+ # obj.method(postmethod).call(*args) if obj.respond_to?(postmethod)
+ # end
+ # end
+ #end
+end
+
+class TreeObject
+ attr_reader :subtype
+ attr_writer :subtype
+ attr_reader :upordown
+ attr_writer :upordown
+ attr_reader :level
+ attr_writer :level
+ attr_reader :parent
+ attr_writer :parent
+ attr_reader :children
+ attr_writer :children
+ attr_writer :closed
+ attr_writer :closed
+ attr_reader :text
+ attr_writer :text
+ attr_reader :visible
+ attr_writer :visible
+
+ include TextArray
+ include ParseTree
+
+ def initialize(subtype=nil)
+ @subtype = subtype
+ @upordown = Same
+ @level = nil
+ @parent = nil
+ @children = []
+ @closed = nil
+ @visible = true
+ end
+
+ def inspect
+ parent, children = @parent, @children
+
+ @parent, @children = parent.id, children.collect{|obj| obj.id}
+
+ res = " " * (level-1) + "#{self.class}(#{@subtype}) #{super}"
+
+ @parent, @children = parent, children
+
+ res
+ end
+end
+
+class Tree
+ @@versie = 1
+ @@mutex = Mutex.new
+
+ attr_reader :data
+ attr_writer :data
+ attr_reader :parent
+ attr_writer :parent
+ attr_reader :children
+ attr_writer :children
+ attr_reader :visible
+ attr_writer :visible
+
+ include TextArray
+ include ParseTree
+
+ def initialize(string)
+ string = string.join("") if string.kind_of?(Array)
+
+ @data = string
+ @parent = nil
+ @children = []
+ @objects = []
+ @visible = true
+ @checkvisibility = false
+
+ buildobjects(string)
+ buildparents
+ buildchildren
+ markclosed
+ deletedummies
+
+ @checkvisibility = true
+ end
+
+ def self.file(file)
+ new(File.new(file).readlines)
+ end
+
+ def self.location(url, form=Hash.new)
+ s = HTTPClient.get(url, form)
+ s = "" if s.nil?
+ new(s)
+ end
+
+ def self.new_from_cache2(data)
+ new(data)
+ end
+
+ def self.new_from_cache(data)
+ hash = MD5.new("#{@@versie} #{data}")
+
+ dir = "#{temp}/evcache.#{user}/tree.new"
+ file = "#{dir}/#{hash}"
+
+ tree = nil
+
+ Dir.mkdirrec(dir)
+
+ if FileTest.file?(file)
+ @@mutex.synchronize do
+ tree = Marshal.restore(File.new(file, "rb"))
+ end
+ else
+ tree = new(data)
+
+ if not tree.nil?
+ @@mutex.synchronize do
+ File.open(file, "wb") {|f| Marshal.dump(tree, f)}
+ end
+ end
+ end
+
+ return tree
+ end
+
+ def inspect
+ @objects.collect do |obj|
+ obj.inspect
+ end.join("\n")
+ end
+
+ def buildobjects(string)
+ raise "Has to be defined in the subclass."
+ end
+
+ def buildparents
+ level = 1
+ levels = Hash.new
+ levels[0] = nil
+ parse do |type, obj|
+ case obj.upordown
+ when Down
+ obj.level = level
+ obj.parent = levels[level-1]
+ levels[level] = obj
+ level += 1
+ when Up, Dummy
+ pl = level
+ 1.upto(level-1) do |l|
+ po = levels[l]
+ pl = l if po.subtype == obj.subtype
+ end
+ level = pl
+ obj.level = level
+ obj.parent = levels[level-1]
+ when Same
+ obj.level = level
+ obj.parent = levels[level-1]
+ end
+ end
+ end
+
+ def buildchildren
+ @objects.each do |obj|
+ obj.children = []
+ end
+
+ parse do |type, obj|
+ if not obj.parent.nil?
+ po = obj.parent
+ po.children << obj
+ else
+ @children << obj
+ end
+ end
+ end
+
+ def markclosed
+ ([self].concat @objects).each do |obj|
+ obj.children.each_index do |i|
+ co1 = obj.children[i]
+ co2 = obj.children[i+1]
+
+ co1.closed = (not co2.nil? and co1.upordown == Down and (co2.upordown == Up or co2.upordown == Dummy) and co1.subtype == co2.subtype)
+ end
+ end
+ end
+
+ def deletedummies
+ ([self].concat @objects).each do |obj|
+ obj.children.delete_if do |obj2|
+ obj2.upordown == Dummy
+ end
+ end
+
+ @objects.delete_if do |obj|
+ obj.upordown == Dummy
+ end
+ end
+
+ def parse(types=[], subtypes=[])
+ types = [types] if types.class == Class
+ subtypes = [subtypes] if subtypes.class == String
+ hidelevel = nil
+
+ @objects.each do |obj|
+ hidelevel = obj.level if (@checkvisibility and hidelevel.nil? and (not obj.visible))
+ hidelevel = nil if (@checkvisibility and (not hidelevel.nil?) and obj.visible and obj.level <= hidelevel)
+
+ if hidelevel.nil?
+ ok = false
+ if types.empty?
+ if subtypes.empty?
+ ok = true
+ else
+ subtypes.each do |st|
+ ok = true if obj.subtype == st
+ end
+ end
+ else
+ if subtypes.empty?
+ types.each do |t|
+ ok = true if obj.kind_of?(t)
+ end
+ else
+ types.each do |t|
+ subtypes.each do |st|
+ ok = true if obj.kind_of?(t) if obj.subtype == st
+ end
+ end
+ end
+ end
+
+ yield(obj.class.to_s, obj) if ok
+ end
+ end
+ end
+
+ def path(pad)
+ p = self
+
+ pad.split(/\//).each do |deel|
+ tag, voorkomen = deel.split(/:/)
+
+ if (not tag.nil?) and (not p.nil?)
+ voorkomen = 1 if voorkomen.nil?
+ voorkomen = voorkomen.to_i
+
+ teller = 0
+ p2 = nil
+ p.children.each_index do |i|
+ if p.children[i].upordown == Down
+ if p.children[i].subtype.noquotes == tag.noquotes
+ teller += 1
+ p2 = p.children[i] if teller == voorkomen
+ end
+ end
+ end
+ p = p2
+ end
+ end
+
+ p
+ end
+end
diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/xml.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/xml.lib.rb
--- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/xml.lib.rb 2004-06-23 00:36:57.000000000 +0200
+++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/xml.lib.rb 2004-04-18 14:20:31.000000000 +0200
@@ -0,0 +1,4 @@
+require "ev/sgml"
+
+class XML < SGML
+end