Module: Parsby::Tree

Included in:
ParsedRange
Defined in:
lib/parsby.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#childrenObject



130
131
132
# File 'lib/parsby.rb', line 130

def children
  @children ||= []
end

#markersObject (readonly)

Returns the value of attribute markers.



119
120
121
# File 'lib/parsby.rb', line 119

def markers
  @markers
end

#parentObject

Returns the value of attribute parent.



118
119
120
# File 'lib/parsby.rb', line 118

def parent
  @parent
end

Instance Method Details

#<<(*ts) ⇒ Object



134
135
136
137
138
139
# File 'lib/parsby.rb', line 134

def <<(*ts)
  ts.each do |t|
    t.parent = self
    children << t
  end
end

#dup(currently_descending: false) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/parsby.rb', line 185

def dup(currently_descending: false)
  self_path = path
  if parent && !currently_descending
    root.dup.get self_path
  else
    super().tap do |d|
      d.children = d.children.map do |c|
        c.dup(currently_descending: true).tap do |dc|
          dc.parent = d
        end
      end
    end
  end
end

#each(&b) ⇒ Object



167
168
169
170
171
# File 'lib/parsby.rb', line 167

def each(&b)
  b.call self
  children.each {|c| c.each(&b) }
  self
end

#flattenObject Also known as: self_and_descendants



157
158
159
# File 'lib/parsby.rb', line 157

def flatten
  [self, *children.map(&:flatten).flatten]
end

#get(path) ⇒ Object



254
255
256
257
258
259
# File 'lib/parsby.rb', line 254

def get(path)
  return self if path.empty?
  idx, *sub_path = path
  child = children[idx]
  child&.get sub_path
end

#pathObject



163
164
165
# File 'lib/parsby.rb', line 163

def path
  [*parent&.path, *sibling_index]
end

#right_tree_sliceObject



181
182
183
# File 'lib/parsby.rb', line 181

def right_tree_slice
  "*" + "|" * right_uncles
end

#right_unclesObject



173
174
175
176
177
178
179
# File 'lib/parsby.rb', line 173

def right_uncles
  if parent
    sibling_reverse_index + parent.right_uncles
  else
    0
  end
end

#rootObject



141
142
143
144
145
146
147
# File 'lib/parsby.rb', line 141

def root
  if parent == nil
    self 
  else
    parent.root
  end
end

#select(&b) ⇒ Object



237
238
239
240
241
242
243
244
245
# File 'lib/parsby.rb', line 237

def select(&b)
  r = []
  each do |n|
    if b.call n
      r << n
    end
  end
  r
end

#select_paths(&b) ⇒ Object



247
248
249
250
251
252
# File 'lib/parsby.rb', line 247

def select_paths(&b)
  root_path = path
  select(&b).map do |n|
    n.path.drop root_path.length
  end
end

#self_and_ancestorsObject



261
262
263
# File 'lib/parsby.rb', line 261

def self_and_ancestors
  [self, *parent&.self_and_ancestors]
end

#sibling_indexObject



153
154
155
# File 'lib/parsby.rb', line 153

def sibling_index
  parent&.children&.index self
end

#sibling_reverse_indexObject



149
150
151
# File 'lib/parsby.rb', line 149

def sibling_reverse_index
  parent&.children&.reverse&.index self
end

#splice(*paths) ⇒ Object



214
215
216
# File 'lib/parsby.rb', line 214

def splice(*paths)
  dup.splice!(*paths)
end

#splice!(*paths) ⇒ Object



207
208
209
210
211
212
# File 'lib/parsby.rb', line 207

def splice!(*paths)
  self.children = paths
    .map {|p| get(p)&.tap {|d| d.parent = self } }
    .reject(&:nil?)
  self
end

#splice_self!Object



200
201
202
203
204
205
# File 'lib/parsby.rb', line 200

def splice_self!
  idx = sibling_index
  parent.children.delete_at(idx)
  parent.children.insert(idx, *children.each {|c| c.parent = parent })
  parent
end

#splice_to!(marker) ⇒ Object



126
127
128
# File 'lib/parsby.rb', line 126

def splice_to!(marker)
  splice!(*select_paths {|n| n.markers.include? marker })
end

#trim_to_just!(*paths, &rejecting) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/parsby.rb', line 218

def trim_to_just!(*paths, &rejecting)
  max_sibling = paths.map(&:first).reject(&:nil?).max
  self.children = if max_sibling.nil?
    []
  else
    children[0..max_sibling]
      .map.with_index {|c, i| [c, i] }
      .reject {|(c, i)| rejecting.call c, i, max_sibling if rejecting }
      .each do |(child, i)|
        subpaths = paths
          .select {|p| p.first == i}
          .map {|p| p.drop 1 }
        child.trim_to_just!(*subpaths, &rejecting)
      end
      .map(&:first)
  end
  self
end