1require 'rexml/encoding'
2require 'rexml/source'
3
4module REXML
5  # NEEDS DOCUMENTATION
6  class XMLDecl < Child
7    include Encoding
8
9    DEFAULT_VERSION = "1.0";
10    DEFAULT_ENCODING = "UTF-8";
11    DEFAULT_STANDALONE = "no";
12    START = '<\?xml';
13    STOP = '\?>';
14
15    attr_accessor :version, :standalone
16    attr_reader :writeencoding, :writethis
17
18    def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
19      @writethis = true
20      @writeencoding = !encoding.nil?
21      if version.kind_of? XMLDecl
22        super()
23        @version = version.version
24        self.encoding = version.encoding
25        @writeencoding = version.writeencoding
26        @standalone = version.standalone
27      else
28        super()
29        @version = version
30        self.encoding = encoding
31        @standalone = standalone
32      end
33      @version = DEFAULT_VERSION if @version.nil?
34    end
35
36    def clone
37      XMLDecl.new(self)
38    end
39
40    # indent::
41    #   Ignored.  There must be no whitespace before an XML declaration
42    # transitive::
43    #   Ignored
44    # ie_hack::
45    #   Ignored
46    def write(writer, indent=-1, transitive=false, ie_hack=false)
47      return nil unless @writethis or writer.kind_of? Output
48      writer << START.sub(/\\/u, '')
49      writer << " #{content encoding}"
50      writer << STOP.sub(/\\/u, '')
51    end
52
53    def ==( other )
54      other.kind_of?(XMLDecl) and
55      other.version == @version and
56      other.encoding == self.encoding and
57      other.standalone == @standalone
58    end
59
60    def xmldecl version, encoding, standalone
61      @version = version
62      self.encoding = encoding
63      @standalone = standalone
64    end
65
66    def node_type
67      :xmldecl
68    end
69
70    alias :stand_alone? :standalone
71    alias :old_enc= :encoding=
72
73    def encoding=( enc )
74      if enc.nil?
75        self.old_enc = "UTF-8"
76        @writeencoding = false
77      else
78        self.old_enc = enc
79        @writeencoding = true
80      end
81      self.dowrite
82    end
83
84    # Only use this if you do not want the XML declaration to be written;
85    # this object is ignored by the XML writer.  Otherwise, instantiate your
86    # own XMLDecl and add it to the document.
87    #
88    # Note that XML 1.1 documents *must* include an XML declaration
89    def XMLDecl.default
90      rv = XMLDecl.new( "1.0" )
91      rv.nowrite
92      rv
93    end
94
95    def nowrite
96      @writethis = false
97    end
98
99    def dowrite
100      @writethis = true
101    end
102
103    def inspect
104      START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
105    end
106
107    private
108    def content(enc)
109      rv = "version='#@version'"
110      rv << " encoding='#{enc}'" if @writeencoding || enc !~ /\Autf-8\z/i
111      rv << " standalone='#@standalone'" if @standalone
112      rv
113    end
114  end
115end
116