File: output.rb

package info (click to toggle)
ruby-htree 0.8%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 448 kB
  • ctags: 703
  • sloc: ruby: 5,931; makefile: 24
file content (212 lines) | stat: -rw-r--r-- 5,135 bytes parent folder | download | duplicates (6)
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 = {
      '>' => '>',
      '<' => '&lt;',
      '"' => '&quot;',
    }

    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