File: tag.rb

package info (click to toggle)
ruby-htree 0.8%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 520 kB
  • sloc: ruby: 5,928; makefile: 23
file content (113 lines) | stat: -rw-r--r-- 3,251 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
require 'htree/raw_string'
require 'htree/text'
require 'htree/scan' # for Pat::Name and Pat::Nmtoken
require 'htree/context'
require 'htree/name'
require 'htree/fstr'

module HTree
  # :stopdoc:

  class STag
    def initialize(name, attributes=[], inherited_context=DefaultContext)
      init_raw_string
      # normalize xml declaration name and attribute value.
      attributes = attributes.map {|aname, val|
        if !(Name === aname) && /\A(?:#{Pat::Name}?\{.*\})?#{Pat::Nmtoken}\z/o !~ aname
          raise HTree::Error, "invalid attribute name: #{aname.inspect}"
        end
        if !(Name === aname) && /\Axmlns(?:\z|:)/ =~ aname
          aname = Name.parse_attribute_name(aname, nil)
        end
        val = val.to_node if HTree::Location === val
        val = Text.new(val) unless Text === val
        [aname, val]
      }

      @inherited_context = inherited_context
      @xmlns_decls = {}

      # validate namespace consistency of given Name objects.
      if Name === name
        @xmlns_decls[name.namespace_prefix] = name.namespace_uri
      end
      attributes.each {|aname, text|
        next unless Name === aname
        next if aname.xmlns?
        if aname.namespace_prefix && aname.namespace_uri
          if @xmlns_decls.include? aname.namespace_prefix
            if @xmlns_decls[aname.namespace_prefix] != aname.namespace_uri
              raise ArgumentError, "inconsistent namespace use: #{aname.namespace_prefix} is used as #{@xmlns_decls[aname.namespace_prefix]} and #{aname.namespace_uri}"
            end
          else
            @xmlns_decls[aname.namespace_prefix] = aname.namespace_uri
          end
        end
      }

      attributes.each {|aname, text|
        next unless Name === aname
        next unless aname.xmlns?
        next if @xmlns_decls.include? aname.local_name
        if aname.local_name
          @xmlns_decls[aname.local_name] = text.to_s
        else
          uri = text.to_s
          @xmlns_decls[nil] = uri
        end
      }

      @context = make_context(@inherited_context)

      if Name === name
        @name = name
      else
        @name = Name.parse_element_name(name, @context)
      end

      @attributes = attributes.map {|aname, text|
        aname = Name.parse_attribute_name(aname, @context) unless Name === aname
        if !aname.namespace_prefix && !aname.namespace_uri.empty?
          # xxx: should recover error?
          raise HTree::Error, "global attribute without namespace prefix: #{aname.inspect}"
        end
        [aname, text]
      }
      @attributes.freeze
    end
    attr_reader :attributes, :inherited_context, :context

    def element_name
      @name
    end

    def make_context(inherited_context)
      inherited_context.subst_namespaces(@xmlns_decls)
    end

    def each_namespace_attribute
      @xmlns_decls.each {|name, uri|
        yield name, uri
      }
      nil
    end

    def each_attribute
      @attributes.each {|name, text|
        next if name.xmlns?
        yield name, text
      }
      nil
    end
  end

  class ETag
    def initialize(qualified_name)
      init_raw_string
      @qualified_name = HTree.frozen_string(qualified_name)
    end
    attr_reader :qualified_name
  end

  # :startdoc:
end