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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
  
     | 
    
      require 'htree/encoder'
require 'htree/doc'
require 'htree/elem'
require 'htree/leaf'
require 'htree/text'
module HTree
  # :stopdoc:
  class Text
    ChRef = {
      '>' => '>',
      '<' => '<',
      '"' => '"',
    }
    def output(out, context=nil)
      out.output_text @rcdata.gsub(/[<>]/) {|s| ChRef[s] }
    end
    def to_attvalue_content
      @rcdata.gsub(/[<>"]/) {|s| ChRef[s] }
    end
    def output_attvalue(out, context)
      out.output_string '"'
      out.output_text to_attvalue_content
      out.output_string '"'
    end
    def output_cdata(out)
      str = self.to_s
      if %r{</} =~ str
        raise ArgumentError, "CDATA cannot contain '</': #{str.inspect}"
      end
      out.output_string(str)
    end
  end
  class Name
    def output(out, context)
      # xxx: validate namespace prefix
      if xmlns?
        if @local_name
          out.output_string "xmlns:#{@local_name}"
        else
          out.output_string "xmlns"
        end
      else
        out.output_string qualified_name
      end
    end
    def output_attribute(text, out, context)
      output(out, context)
      out.output_string '='
      text.output_attvalue(out, context)
    end
  end
  class Doc
    def output(out, context)
      xmldecl = false
      @children.each {|n|
        if n.respond_to? :output_prolog_xmldecl
          n.output_prolog_xmldecl(out, context) unless xmldecl # xxx: encoding?
          xmldecl = true
        else
          n.output(out, context)
        end
      }
    end
  end
  class Elem
    def output(out, context)
      if %r{\A\{http://www.w3.org/1999/xhtml\}(?:script|style)\z} =~ @stag.element_name.universal_name
        children_context = @stag.output_stag(out, context)
        out.output_cdata_content(@children, children_context)
        @stag.output_etag(out, context)
      elsif @empty
        @stag.output_emptytag(out, context)
      else
        children_context = @stag.output_stag(out, context)
        @children.each {|n| n.output(out, children_context) }
        @stag.output_etag(out, context)
      end
    end
  end
  class STag
    def output_attributes(out, context)
      @attributes.each {|aname, text|
        next if aname.xmlns?
        out.output_string ' '
        aname.output_attribute(text, out, context)
      }
      @context.output_namespaces(out, context)
    end
    def output_emptytag(out, context)
      out.output_string '<'
      @name.output(out, context)
      children_context = output_attributes(out, context)
      out.output_string "\n"
      out.output_slash_if_xml
      out.output_string ">"
      children_context
    end
    def output_stag(out, context)
      out.output_string '<'
      @name.output(out, context)
      children_context = output_attributes(out, context)
      out.output_string "\n>"
      children_context
    end
    def output_etag(out, context)
      out.output_string '</'
      @name.output(out, context)
      out.output_string "\n>"
    end
  end
  class Context
    def output_namespaces(out, outer_context)
      unknown_namespaces = {}
      @namespaces.each {|prefix, uri|
        outer_uri = outer_context.namespace_uri(prefix)
        if outer_uri == nil
          unknown_namespaces[prefix] = uri
        elsif outer_uri != uri
          if prefix
            out.output_string " xmlns:#{prefix}="
          else
            out.output_string " xmlns="
          end
          Text.new(uri).output_attvalue(out, outer_context)
        end
      }
      unless unknown_namespaces.empty?
        out.output_xmlns(unknown_namespaces)
      end
      outer_context.subst_namespaces(@namespaces)
    end
  end
  class BogusETag
    # don't output anything.
    def output(out, context)
    end
  end
  class XMLDecl
    # don't output anything.
    def output(out, context)
    end
    def output_prolog_xmldecl(out, context)
      out.output_string "<?xml version=\"#{@version}\""
      if @encoding
        out.output_string " encoding=\"#{@encoding}\""
      end
      if @standalone != nil
        out.output_string " standalone=\"#{@standalone ? 'yes' : 'no'}\""
      end
      out.output_string "?>"
    end
  end
  class DocType
    def output(out, context)
      out.output_string "<!DOCTYPE #{@root_element_name} #{generate_content}>"
    end
    def generate_content # :nodoc:
      result = ''
      if @public_identifier
        result << "PUBLIC \"#{@public_identifier}\""
      else
        result << "SYSTEM"
      end
      # Although a system identifier is not omissible in XML,
      # we cannot output it if it is not given.
      if @system_identifier
        if /"/ !~ @system_identifier
          result << " \"#{@system_identifier}\""
        else
          result << " '#{@system_identifier}'"
        end
      end
      result
    end
  end
  class ProcIns
    def output(out, context)
      out.output_string "<?#{@target}"
      out.output_string " #{@content}" if @content
      out.output_string "?>"
    end
  end
  class Comment
    def output(out, context)
      out.output_string "<!--#{@content}-->"
    end
  end
  # :startdoc:
end
 
     |