Method: HTree::Doc#subst_subnode

Defined in:
lib/htree/doc.rb

#subst_subnode(pairs) ⇒ Object

doc.subst_subnode(pairs) -> doc

The argument pairs should be a hash or an assocs. Its key should be an integer which means an index for children.

Its value should be one of follows.

HTree::Node object

specified object is used as is.

String object

specified string is converted to HTree::Text

Array of above

specified HTree::Node and String is used in that order.

nil

delete corresponding node.

d = HTree('<a/><b/><c/>')        
p d.subst_subnode({0=>HTree('<x/>'), 2=>HTree('<z/>')})
p d.subst_subnode([[0,HTree('<x/>')], [2,HTree('<z/>')]])
# =>
#<HTree::Doc {emptyelem <x>} {emptyelem <b>} {emptyelem <z>}>
#<HTree::Doc {emptyelem <x>} {emptyelem <b>} {emptyelem <z>}>


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
# File 'lib/htree/doc.rb', line 94

def subst_subnode(pairs)
  hash = {}
  pairs.each {|index, value|
    unless Integer === index
      raise TypeError, "invalid index: #{index.inspect}"
    end
    value = value.to_node if HTree::Location === value
    case value
    when Node
      value = [value]
    when String
      value = [value]
    when Array
      value = value.dup
    when nil
      value = []
    else
      raise TypeError, "invalid value: #{value.inspect}"
    end
    value.map! {|v|
      v = v.to_node if HTree::Location === v
      case v
      when Node
        v
      when String
        Text.new(v)
      else
        raise TypeError, "invalid value: #{v.inspect}"
      end
    }
    if !hash.include?(index)
      hash[index] = []
    end
    hash[index].concat value
  }

  children_left = []
  children = @children.dup
  children_right = []

  hash.keys.sort.each {|index|
    value = hash[index]
    if index < 0
      children_left << value
    elsif children.length <= index
      children_right << value
    else
      children[index] = value
    end
  }

  children = [children_left, children, children_right].flatten.compact
  Doc.new(children)
end