#!/usr/local/bin/ruby -Ku
# MWDOM XMLScanTreeBuilder
# Copyright (c)2001, MoonWolf. All right reserved.
require "xmlscan"
require "mwdom/core.rb"

module MWDOM
  class XMLScanTreeBuilder < XMLScannerWithNamespace
    def initialize
      super
      impl = MWDOM::DOMImplementation.instance
      @prologue = nil
      @document = impl.createDocument(nil,nil,nil)
      @parent=[@document]
    end
    attr_reader :document,:prologue
    
    private
    
    def on_error(path, lineno, msg)
      raise ParseError, sprintf('%s:%d: %s', path, lineno, msg)
    end
    
    def on_xmldecl(version, encoding, standalone)
      super
      xmldecl = "<?xml version=\"#{version}\""
      xmldecl << " encoding=\"#{encoding}\"" if encoding
      xmldecl << " standalone=\"#{standalone}\"" if standalone
      xmldecl << " ?>"
      @prologue = xmldecl
    end
    
    def on_doctype(root, pubid, sysid)
      super
      impl = MWDOM::DOMImplementation.instance
      doctype = impl.createDocumentType(root, pubid, sysid)
      @document.appendChild(doctype)
    end
    
    def on_comment(strs)
      super
      node = @document.createComment(strs.to_s)
      @parent.last.appendChild(node)
    end
      
    def on_pi(target, pi)
      super
      node = @document.createProcessingInstruction(target, pi)
      @parent.last.appendChild(node)
    end
    
    def on_chardata(str)
      super
      node = @document.createTextNode(str)
      @parent.last.appendChild(node)
    end
    
    def on_etag(name)
      super
      @parent.pop
    end
    
    def on_stag(name, attr)
      super
      (ns, prefix, name) = expand_qualified_name(name,@elemstack.default_namespace)
      elem = @document.createElementNS(ns,(prefix ? prefix+':'+name : name))
      expand_attr_namespace(attr).each {|ns,attrs|
        attrs.each {|key,value|
          elem.setAttributeNS(ns,key,value)
        }
      }
      @parent.last.appendChild(elem)
      @parent.push elem
    end
    
    def on_emptyelem(name, attr)
      super
      (ns, prefix, name) = expand_qualified_name(name,@elemstack.default_namespace)
      elem = @document.createElementNS(ns,(prefix ? prefix+':'+name : name))
      expand_attr_namespace(attr).each {|ns,attrs|
        attrs.each {|key,value|
          elem.setAttributeNS(ns,key,value)
        }
      }
      @parent.last.appendChild(elem)
    end
    
    def on_entityref(ref)
      super
      node = @document.createEntityReference(ref)
      @parent.last.appendChild(node)
    end
    
    def on_charref(ref)
      super
    end
    
    def on_eof
      super
    end
  end
end

if __FILE__==$0
  src = ARGF.read
  scan = MWDOM::XMLScanTreeBuilder.new
  scan.parse(src)
  print scan.document.to_s
end
