Class: Origami::PageTreeNode

Inherits:
Dictionary show all
Includes:
StandardObject
Defined in:
lib/origami/page.rb

Overview

Class representing a node in a Page tree.

Constant Summary

Constants included from StandardObject

StandardObject::DEFAULT_ATTRIBUTES

Constants inherited from Dictionary

Dictionary::TOKENS

Constants included from Object

Object::TOKENS

Instance Attribute Summary

Attributes inherited from Dictionary

#names_cache, #strings_cache, #xref_cache

Attributes included from Object

#file_offset, #generation, #no, #objstm_offset, #parent

Instance Method Summary collapse

Methods included from StandardObject

included, #version_required

Methods inherited from Dictionary

#[], #[]=, add_type_signature, #cast_to, #copy, #delete, guess_type, hint_type, #key?, #map!, #merge, parse, #to_h, #to_obfuscated_str, #to_s

Methods included from FieldAccessor

#method_missing, #respond_to_missing?

Methods included from Object

#<=>, #cast_to, #copy, #document, #export, included, #indirect?, #indirect_parent, #logicalize, #logicalize!, #native_type, parse, #post_build, #reference, #set_document, #set_indirect, skip_until_next_obj, #solve, #to_o, #to_s, #type, typeof, #version_required, #xrefs

Constructor Details

#initialize(hash = {}, parser = nil) ⇒ PageTreeNode

Returns a new instance of PageTreeNode.


288
289
290
291
292
293
294
295
# File 'lib/origami/page.rb', line 288

def initialize(hash = {}, parser = nil)
    self.Count = 0
    self.Kids = []

    super

    set_indirect(true)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Origami::FieldAccessor

Instance Method Details

#<<(pageset) ⇒ Object


420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/origami/page.rb', line 420

def <<(pageset)
    pageset = [pageset] unless pageset.is_a?(::Array)
    unless pageset.all? {|item| item.is_a?(Page) or item.is_a?(PageTreeNode) }
        raise TypeError, "Cannot add anything but Page and PageTreeNode to this node"
    end

    self.Kids ||= Array.new
    self.Kids.concat(pageset)
    self.Count = self.Kids.length

    pageset.each do |node|
        node.Parent = self
    end
end

#each_page(browsed_nodes: [], &block) ⇒ Object

Iterate through each page of that node.


353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/origami/page.rb', line 353

def each_page(browsed_nodes: [], &block)
    return enum_for(__method__) { self.Count.to_i } unless block_given?

    if browsed_nodes.any?{|node| node.equal?(self)}
        raise InvalidPageTreeError, "Cyclic tree graph detected"
    end

    unless self.Kids.is_a?(Array)
        raise InvalidPageTreeError, "Kids must be an Array"
    end

    browsed_nodes.push(self)

    unless self.Count.nil?
        [ self.Count.value, self.Kids.length ].min.times do |n|
            node = self.Kids[n].solve

            case node
            when PageTreeNode then node.each_page(browsed_nodes: browsed_nodes, &block)
            when Page then yield(node)
            else
                raise InvalidPageTreeError, "not a Page or PageTreeNode"
            end
        end
    end

    self
end

#get_page(n, browsed_nodes: []) ⇒ Object

Get the n-th Page object in this node, starting from 1.

Raises:

  • (IndexError)

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/origami/page.rb', line 385

def get_page(n, browsed_nodes: [])
    raise IndexError, "Page numbers are referenced starting from 1" if n < 1

    if browsed_nodes.any?{|node| node.equal?(self)}
        raise InvalidPageTreeError, "Cyclic tree graph detected"
    end

    unless self.Kids.is_a?(Array)
        raise InvalidPageTreeError, "Kids must be an Array"
    end

    decount = n
    [ self.Count.value, self.Kids.length ].min.times do |i|
        node = self.Kids[i].solve

        case node
        when Page
            decount = decount - 1
            return node if decount == 0

        when PageTreeNode
            nchilds = [ node.Count.value, node.Kids.length ].min
            if nchilds >= decount
                return node.get_page(decount, browsed_nodes: browsed_nodes)
            else
                decount -= nchilds
            end
        else
            raise InvalidPageTreeError, "not a Page or PageTreeNode"
        end
    end

    raise IndexError, "Page not found"
end

#insert_page(index, page) ⇒ Object

Raises:

  • (IndexError)

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/origami/page.rb', line 303

def insert_page(index, page)
    raise IndexError, "Invalid index for page tree" if index > self.Count

    count = 0
    kids = self.Kids

    kids.length.times do |n|
        if count == index
            kids.insert(n, page)
            self.Count = self.Count + 1
            page.Parent = self
            return self
        else
            node = kids[n].solve
            case node
            when Page
                count = count + 1
                next
            when PageTreeNode
                if count + node.Count > index
                    node.insert_page(index - count, page)
                    self.Count = self.Count + 1
                    return self
                else
                    count = count + node.Count
                    next
                end
            end
        end
    end

    if count == index
        self << page
    else
        raise IndexError, "An error occured while inserting page"
    end

    self
end

#pagesObject

Returns an Array of Pages inheriting this tree node.


346
347
348
# File 'lib/origami/page.rb', line 346

def pages
    self.each_page.to_a
end

#pre_buildObject

:nodoc:


297
298
299
300
301
# File 'lib/origami/page.rb', line 297

def pre_build #:nodoc:
    self.Count = self.pages.count

    super
end