Parent

Prawn::Outline

The Outline class organizes the outline tree items for the document. Note that the prev and parent instance variables are adjusted while navigating through the nested blocks. These variables along with the presence or absense of blocks are the primary means by which the relations for the various OutlineItems and the OutlineRoot are set. Unfortunately, the best way to understand how this works is to follow the method calls through a real example.

Some ideas for the organization of this class were gleaned from name_tree. In particular the way in which the OutlineItems are finally rendered into document objects in PdfObject through a hash.

Attributes

parent[RW]
prev[RW]
document[RW]
items[RW]

Public Class Methods

new(document) click to toggle source
    # File lib/prawn/outline.rb, line 42
42:     def initialize(document)
43:       @document = document
44:       @parent = root
45:       @prev = nil
46:       @items = {}
47:     end

Public Instance Methods

add_subsection_to(title, position = :last, &block) click to toggle source

Inserts an outline section to the outline tree (see outline#). Although you will probably choose to exclusively use outline# so that your outline tree is contained and easy to manage, this method gives you the option to insert sections to the outline tree at any point during document generation. This method allows you to add a child subsection to any other item at any level in the outline tree. Currently the only way to locate the place of entry is with the title for the item. If your title names are not unique consider using define_outline. The method takes the following arguments:

  title: a string that must match an outline title to add the subsection to
  position: either :first or :last(the default) where the subsection will be placed relative 
     to other child elements. If you need to position your subsection in between 
     other elements then consider using #insert_section_after   
  block: uses the same DSL syntax as outline#define, for example: 

Consider using this method inside of outline.update if you want to have the outline object to be scoped as self (see # example).

  go_to_page 2
  start_new_page
  text "Inserted Page"
  outline.add_subsection_to :title => 'Page 2', :first do 
    outline.page :destination => page_number, :title => "Inserted Page"
  end
     # File lib/prawn/outline.rb, line 108
108:     def add_subsection_to(title, position = :last, &block)
109:       @parent = items[title]
110:       raise Prawn::Errors::UnknownOutlineTitle, 
111:         "\n No outline item with title: '#{title}' exists in the outline tree" unless @parent
112:       @prev = position == :first ? nil : @parent.data.last
113:       nxt = position == :first ? @parent.data.first : nil
114:       insert_section(nxt, &block)  
115:     end
define(&block) click to toggle source

Defines/Updates an outline for the document. The outline is an optional nested index that appears on the side of a PDF document usually with direct links to pages. The outline DSL is defined by nested blocks involving two methods: section and page; see the documentation on those methods for their arguments and options. Note that one can also use outline# to add more sections to the end of the outline tree using the same syntax and scope.

The syntax is best illustrated with an example:

Prawn::Document.generate(outlined_document.pdf) do

  text "Page 1. This is the first Chapter. "
  start_new_page
  text "Page 2. More in the first Chapter. "
  start_new_page
  outline.define do
    section 'Chapter 1', :destination => 1, :closed => true do 
      page :destination => 1, :title => 'Page 1'
      page :destination => 2, :title => 'Page 2'
    end
  end 
  start_new_page do
  outline.update do 
    section 'Chapter 2', :destination =>  2, do
      page :destination => 3, :title => 'Page 3'
    end
  end

end

    # File lib/prawn/outline.rb, line 77
77:     def define(&block)
78:       instance_eval(&block)  if block
79:     end
Also aliased as: update
insert_section_after(title, &block) click to toggle source

Inserts an outline section to the outline tree (see outline#). Although you will probably choose to exclusively use outline# so that your outline tree is contained and easy to manage, this method gives you the option to insert sections to the outline tree at any point during document generation. Unlike outline.add_section, this method allows you to enter a section after any other item at any level in the outline tree. Currently the only way to locate the place of entry is with the title for the item. If your title names are not unique consider using define_outline. The method takes the following arguments:

  title: the title of other section or page to insert new section after
  block: uses the same DSL syntax as outline#define, for example: 

  go_to_page 2
  start_new_page
  text "Inserted Page"
  update_outline do
    insert_section_after :title => 'Page 2' do 
      page :destination => page_number, :title => "Inserted Page" 
    end
  end
     # File lib/prawn/outline.rb, line 138
138:     def insert_section_after(title, &block)
139:       @prev = items[title]
140:       raise Prawn::Errors::UnknownOutlineTitle, 
141:         "\n No outline item with title: '#{title}' exists in the outline tree" unless @prev
142:       @parent = @prev.data.parent
143:       nxt = @prev.data.next
144:       insert_section(nxt, &block)   
145:     end
page(options = {}) click to toggle source

See Outline#define above for more documentation on how it is used in that context

Adds a page to the outline. Although you will probably choose to exclusively use outline# so that your outline tree is contained and easy to manage, this method also gives you the option to add pages to the root of outline tree at any point during document generation. Note that the page will be added at the top level after the other root outline elements. For more flexible placement try using outline# and/or outline#.

Takes the following arguments:

    options:
           title - REQUIRED. The outline text that appears for the page. 
           destination - integer defining the page number for the destination link.
             currently only :FIT destination supported with link to top of page.
           closed - whether the section should show its nested outline elements.
                  * defaults to false.

example usage:

  outline.page :title => "Very Last Page" 

Note: this method is almost identical to section except that it does not accept a block thereby defining the outline item as a leaf on the outline tree structure.

     # File lib/prawn/outline.rb, line 196
196:     def page(options = {})
197:       if options[:title]
198:         title = options[:title] 
199:       else
200:         raise Prawn::Errors::RequiredOption, 
201:           "\nTitle is a required option for page"
202:       end
203:       add_outline_item(title, options)
204:     end
section(title, options = {}, &block) click to toggle source

See outline# above for documentation on how this is used in that context

Adds an outine section to the outline tree. Although you will probably choose to exclusively use outline# so that your outline tree is contained and easy to manage, this method gives you the option to add sections to the outline tree at any point during document generation. When not being called from within another # block the section will be added at the top level after the other root elements of the outline. For more flexible placement try using outline# and/or outline# Takes the following arguments:

  title: the outline text that appears for the section.
  options: destination - optional integer defining the page number for a destination link.
                * currently only :FIT destination supported with link to top of page.
           closed - whether the section should show its nested outline elements.
                  * defaults to false. 
           block: more nested subsections and/or page blocks 
  

example usage:

  outline.section 'Added Section', :destination => 3 do
    outline.page :destionation => 3, :title => 'Page 3'
  end
     # File lib/prawn/outline.rb, line 170
170:     def section(title, options = {}, &block)
171:       add_outline_item(title, options, &block)
172:     end
update(&block) click to toggle source
Alias for: define

Private Instance Methods

add_outline_item(title, options, &block) click to toggle source
     # File lib/prawn/outline.rb, line 215
215:     def add_outline_item(title, options, &block)
216:       outline_item = create_outline_item(title, options)
217:       set_relations(outline_item)
218:       increase_count
219:       set_variables_for_block(outline_item, block)
220:       block.call if block
221:       reset_parent(outline_item)
222:     end
adjust_relations(nxt, last) click to toggle source
     # File lib/prawn/outline.rb, line 275
275:     def adjust_relations(nxt, last)
276:       if nxt 
277:         nxt.data.prev = @prev
278:         @prev.data.next = nxt
279:         @parent.data.last = last
280:       end
281:     end
create_outline_item(title, options) click to toggle source
     # File lib/prawn/outline.rb, line 224
224:     def create_outline_item(title, options)
225:       outline_item = OutlineItem.new(title, parent, options)
226: 
227:       if options[:destination]
228:         page_index = options[:destination] - 1
229:         outline_item.dest = [document.state.pages[page_index].dictionary, :Fit] 
230:       end
231: 
232:       outline_item.prev = prev if @prev
233:       items[title] = document.ref!(outline_item)
234:     end
increase_count() click to toggle source
     # File lib/prawn/outline.rb, line 242
242:     def increase_count
243:       counting_parent = parent
244:       while counting_parent
245:         counting_parent.data.count += 1
246:         if counting_parent == root
247:           counting_parent = nil
248:         else
249:           counting_parent = counting_parent.data.parent
250:         end
251:       end
252:     end
insert_section(nxt, &block) click to toggle source
     # File lib/prawn/outline.rb, line 266
266:     def insert_section(nxt, &block)
267:       last = @parent.data.last
268:       if block
269:         block.call
270:       end
271:       adjust_relations(nxt, last)
272:       reset_root_positioning
273:     end
reset_parent(outline_item) click to toggle source
     # File lib/prawn/outline.rb, line 259
259:     def reset_parent(outline_item)
260:       if parent == outline_item
261:         self.prev = outline_item
262:         self.parent = outline_item.data.parent
263:       end
264:     end
reset_root_positioning() click to toggle source
     # File lib/prawn/outline.rb, line 283
283:     def reset_root_positioning
284:       @parent = root
285:       @prev = root.data.last
286:     end
root() click to toggle source

The Outline dictionary (12.3.3) for this document. It is lazily initialized, so that documents that do not have an outline do not incur the additional overhead.

     # File lib/prawn/outline.rb, line 211
211:     def root
212:       document.state.store.root.data[:Outlines] ||= document.ref!(OutlineRoot.new)
213:     end
set_relations(outline_item) click to toggle source
     # File lib/prawn/outline.rb, line 236
236:     def set_relations(outline_item)
237:       prev.data.next = outline_item if prev
238:       parent.data.first = outline_item unless prev
239:       parent.data.last = outline_item
240:     end
set_variables_for_block(outline_item, block) click to toggle source
     # File lib/prawn/outline.rb, line 254
254:     def set_variables_for_block(outline_item, block)
255:       self.prev = block ? nil : outline_item
256:       self.parent = outline_item if block
257:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.