# encoding: utf-8 # # repeater.rb : Implements repeated page elements. # Heavy inspired by repeating_element() in PDF::Wrapper # http://pdf-wrapper.rubyforge.org/ # # Copyright November 2009, Gregory Brown. All Rights Reserved. # # This is free software. Please see the LICENSE and COPYING files for details. module Prawn class Document # A list of all repeaters in the document. # See Document#repeat for details # def repeaters @repeaters ||= [] end # Provides a way to execute a block of code repeatedly based on a # page_filter. Since Stamp is used under the hood, this method is very space # efficient. # # Available page filters are: # :all -- repeats on every page # :odd -- repeats on odd pages # :even -- repeats on even pages # some_array -- repeats on every page listed in the array # some_range -- repeats on every page included in the range # some_lambda -- yields page number and repeats for true return values # # Also accepts an optional second argument for dynamic content which executes the code # in the context of the filtered pages without using a Stamp. # # Example: # # Prawn::Document.generate("repeat.pdf", :skip_page_creation => true) do # # repeat :all do # draw_text "ALLLLLL", :at => bounds.top_left # end # # repeat :odd do # draw_text "ODD", :at => [0,0] # end # # repeat :even do # draw_text "EVEN", :at => [0,0] # end # # repeat [1,2] do # draw_text "[1,2]", :at => [100,0] # end # # repeat 2..4 do # draw_text "2..4", :at => [200,0] # end # # repeat(lambda { |pg| pg % 3 == 0 }) do # draw_text "Every third", :at => [250, 20] # end # # 10.times do # start_new_page # draw_text "A wonderful page", :at => [400,400] # end # # repeat(:all, :dynamic => true) do # text page_number, :at => [500, 0] # end # # end # def repeat(page_filter, options={}, &block) repeaters << Prawn::Repeater.new(self, page_filter, !!options[:dynamic], &block) end end class Repeater #:nodoc: class << self attr_writer :count def count @count ||= 0 end end attr_reader :name def initialize(document, page_filter, dynamic = false, &block) @document = document @page_filter = page_filter @dynamic = dynamic @stamp_name = "prawn_repeater(#{Repeater.count})" @document.create_stamp(@stamp_name, &block) unless dynamic @block = block if dynamic @graphic_state = document.state.page.graphic_state.dup Repeater.count += 1 end def match?(page_number) @document.page_match?(@page_filter, page_number) end def run(page_number) if !@dynamic @document.stamp(@stamp_name) if match?(page_number) elsif @block @document.save_graphics_state(@graphic_state) do @document.send(:freeze_stamp_graphics) @block.call end end end end end