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

#do_type_check, #has_field?, included, #set_default_value, #set_default_values, #version_required

Methods inherited from Dictionary

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

Methods included from Object

#<=>, #cast_to, #copy, #document, #export, #indirect?, #indirect_parent, #logicalize, #logicalize!, native_type, #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.



292
293
294
295
296
297
298
299
# File 'lib/origami/page.rb', line 292

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

    super(hash, parser)

    set_indirect(true)
end

Dynamic Method Handling

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

Instance Method Details

#<<(pageset) ⇒ Object



424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/origami/page.rb', line 424

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.



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

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)


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
419
420
421
422
# File 'lib/origami/page.rb', line 389

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)


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
342
343
344
345
# File 'lib/origami/page.rb', line 307

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.



350
351
352
# File 'lib/origami/page.rb', line 350

def pages
    self.each_page.to_a
end

#pre_buildObject

:nodoc:



301
302
303
304
305
# File 'lib/origami/page.rb', line 301

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

    super
end