diff --git a/lib/prawn/document.rb b/lib/prawn/document.rb index eb71dcb87..d91dd8739 100644 --- a/lib/prawn/document.rb +++ b/lib/prawn/document.rb @@ -62,6 +62,14 @@ class Document include Prawn::Stamp include Prawn::SoftMask + # NOTE: We probably need to rethink the options validation system, but this + # constant temporarily allows for extensions to modify the list. + + VALID_OPTIONS = [:page_size, :page_layout, :margin, :left_margin, + :right_margin, :top_margin, :bottom_margin, :skip_page_creation, + :compress, :skip_encoding, :background, :info, + :optimize_objects, :text_formatter, :print_scaling] + # Any module added to this array will be included into instances of # Prawn::Document at the per-object level. These will also be inherited by # any subclasses. @@ -138,7 +146,6 @@ def self.generate(filename,options={},&block) # :background:: An image path to be used as background on all pages [nil] # :background_scale:: Backgound image scale [1] [nil] # :info:: Generic hash allowing for custom metadata properties [nil] - # :template:: The path to an existing PDF file to use as a template [nil] # :text_formatter: The text formatter to use for :inline_formatted text [Prawn::Text::Formatted::Parser] # # Setting e.g. the :margin to 100 points and the :left_margin to 50 will result in margins @@ -173,12 +180,7 @@ def self.generate(filename,options={},&block) def initialize(options={},&block) options = options.dup - Prawn.verify_options [:page_size, :page_layout, :margin, :left_margin, - :right_margin, :top_margin, :bottom_margin, :skip_page_creation, - :compress, :skip_encoding, :background, :info, - :optimize_objects, :template, :text_formatter, :print_scaling], options - - + Prawn.verify_options VALID_OPTIONS, options # need to fix, as the refactoring breaks this # raise NotImplementedError if options[:skip_page_creation] @@ -204,16 +206,7 @@ def initialize(options={},&block) options[:size] = options.delete(:page_size) options[:layout] = options.delete(:page_layout) - if options[:template] - fresh_content_streams(options) - go_to_page(1) - else - if options[:skip_page_creation] || options[:template] - start_new_page(options.merge(:orphan => true)) - else - start_new_page(options) - end - end + initialize_first_page(options) @bounding_box = @margin_box @@ -236,6 +229,14 @@ def page state.page end + def initialize_first_page(options) + if options[:skip_page_creation] + start_new_page(options.merge(:orphan => true)) + else + start_new_page(options) + end + end + # Creates and advances to a new page in the document. # # Page size, margins, and layout can also be set when generating a @@ -246,14 +247,6 @@ def page # pdf.start_new_page(:left_margin => 50, :right_margin => 50) # pdf.start_new_page(:margin => 100) # - # A template for a page can be specified by pointing to the path of and existing pdf. - # One can also specify which page of the template which defaults otherwise to 1. - # - # pdf.start_new_page(:template => multipage_template.pdf, :template_page => 2) - # - # Note: templates get indexed by either the object_id of the filename or stream - # entered so that if you reuse the same template multiple times be sure to use the - # same instance for more efficient use of resources and smaller rendered pdfs. def start_new_page(options = {}) if last_page = state.page last_page_size = last_page.size @@ -270,7 +263,6 @@ def start_new_page(options = {}) new_graphic_state.color_space = {} if new_graphic_state page_options.merge!(:graphic_state => new_graphic_state) end - merge_template_options(page_options, options) if options[:template] state.page = PDF::Core::Page.new(self, page_options) @@ -283,9 +275,7 @@ def start_new_page(options = {}) @bounding_box = @margin_box end - state.page.new_content_stream if options[:template] - use_graphic_settings(options[:template]) - forget_text_rendering_mode! if options[:template] + use_graphic_settings unless options[:orphan] state.insert_page(state.page, @page_number) @@ -655,13 +645,8 @@ def compression_enabled? private - def merge_template_options(page_options, options) - object_id = state.store.import_page(options[:template], options[:template_page] || 1) - page_options.merge!(:object_id => object_id, :page_template => true) - end - # setting override_settings to true ensures that a new graphic state does not end up using - # previous settings especially from imported template streams + # previous settings. def use_graphic_settings(override_settings = false) set_fill_color if current_fill_color != "000000" || override_settings set_stroke_color if current_stroke_color != "000000" || override_settings diff --git a/lib/prawn/templates.rb b/lib/prawn/templates.rb new file mode 100644 index 000000000..b95530ffe --- /dev/null +++ b/lib/prawn/templates.rb @@ -0,0 +1,75 @@ +warn "Templates are no longer supported in Prawn!\n" + + "This code is for experimental testing only, and\n" + + "will extracted into its own gem in a future Prawn release" + +module Prawn + module Templates + def initialize_first_page(options) + return super unless options[:template] + + fresh_content_streams(options) + go_to_page(1) + end + + ## FIXME: This is going to be terribly brittle because + # it copy-pastes the start_new_page method. But at least + # it should only run when templates are used. + + def start_new_page(options = {}) + return super unless options[:template] + + if last_page = state.page + last_page_size = last_page.size + last_page_layout = last_page.layout + last_page_margins = last_page.margins + end + + page_options = {:size => options[:size] || last_page_size, + :layout => options[:layout] || last_page_layout, + :margins => last_page_margins} + if last_page + new_graphic_state = last_page.graphic_state.dup if last_page.graphic_state + #erase the color space so that it gets reset on new page for fussy pdf-readers + new_graphic_state.color_space = {} if new_graphic_state + page_options.merge!(:graphic_state => new_graphic_state) + end + + merge_template_options(page_options, options) + + state.page = PDF::Core::Page.new(self, page_options) + + apply_margin_options(options) + generate_margin_box + + # Reset the bounding box if the new page has different size or layout + if last_page && (last_page.size != state.page.size || + last_page.layout != state.page.layout) + @bounding_box = @margin_box + end + + state.page.new_content_stream + use_graphic_settings(true) + forget_text_rendering_mode! + + unless options[:orphan] + state.insert_page(state.page, @page_number) + @page_number += 1 + + canvas { image(@background, :scale => @background_scale, :at => bounds.top_left) } if @background + @y = @bounding_box.absolute_top + + float do + state.on_page_create_action(self) + end + end + end + + def merge_template_options(page_options, options) + object_id = state.store.import_page(options[:template], options[:template_page] || 1) + page_options.merge!(:object_id => object_id, :page_template => true) + end + end +end + +Prawn::Document::VALID_OPTIONS << :template +Prawn::Document.extensions << Prawn::Templates diff --git a/manual/manual/manual.rb b/manual/manual/manual.rb index 6d1ff38f0..a7dd6aaf7 100644 --- a/manual/manual/manual.rb +++ b/manual/manual/manual.rb @@ -30,6 +30,5 @@ load_package "document_and_page_options" load_package "outline" load_package "repeatable_content" - load_package "templates" load_package "security" end diff --git a/manual/templates/full_template.rb b/manual/templates/full_template.rb deleted file mode 100644 index eb4e52afb..000000000 --- a/manual/templates/full_template.rb +++ /dev/null @@ -1,25 +0,0 @@ -# encoding: utf-8 -# -#NOTE: Templates are currently unmaintained and may be removed by Prawn 1.0! -# -# You may load another PDF while creating a new one. Just pass the loaded PDF -# filename to the :template option when creating/generating the new -# PDF. -# -# The provided PDF will be loaded and its first page will be set as the -# current page. If you'd like to resume the document you may take advantage of -# two helpers: page_count and go_to_page. -# -require File.expand_path(File.join(File.dirname(__FILE__), - %w[.. example_helper])) - -filename = "#{Prawn::DATADIR}/pdfs/multipage_template.pdf" - -Prawn::Example.generate("full_template.pdf", :template => filename) do - go_to_page(page_count) - - start_new_page - - text "Previous pages and content imported.", :align => :center - text "This page and content is brand new.", :align => :center -end diff --git a/manual/templates/page_template.rb b/manual/templates/page_template.rb deleted file mode 100644 index d4112a8d9..000000000 --- a/manual/templates/page_template.rb +++ /dev/null @@ -1,48 +0,0 @@ -# encoding: utf-8 -# NOTE: Templates are currently unmaintained and may be removed by Prawn 1.0! -# -# If you only need to load some pages from another PDF, you can accomplish it -# with the start_new_page method. You may pass it a -# :template option with the path for an existing pdf and a -# :template_page option to specify which page to load. -# You can also load a :template using a URI: -# -# require 'open-uri' -# -# start_new_page(:template => open('url_for_your.pdf')) -# -# The following example loads some pages from an existing PDF. If we don't -# specify the :template_page option, the first page of the template -# PDF will be loaded. That's what happens on the first load below. Then we load -# a page by specifying the :template_page option and then we do it -# again this time adding some content to the loaded page. -# -require File.expand_path(File.join(File.dirname(__FILE__), - %w[.. example_helper])) - -filename = File.basename(__FILE__).gsub('.rb', '.pdf') -Prawn::Example.generate(filename) do - text "Please scan the next 3 pages to see the page templates in action." - move_down 10 - text "You also might want to look at the pdf used as a template: " - url = "https://github.com/prawnpdf/prawn/raw/master/data/pdfs/form.pdf" - move_down 10 - - formatted_text [{:text => url, :link => url}] - - filename = "#{Prawn::DATADIR}/pdfs/form.pdf" - start_new_page(:template => filename) - - start_new_page(:template => filename, :template_page => 2) - - start_new_page(:template => filename, :template_page => 2) - - fill_color "FF8888" - - text_box "John Doe", :at => [75, cursor-75] - text_box "john@doe.com", :at => [75, cursor-105] - text_box "John Doe inc", :at => [75, cursor-135] - text_box "You didn't think I'd tell, did you?", :at => [75, cursor-165] - - fill_color "000000" -end diff --git a/manual/templates/templates.rb b/manual/templates/templates.rb deleted file mode 100644 index 7c3d237c5..000000000 --- a/manual/templates/templates.rb +++ /dev/null @@ -1,27 +0,0 @@ -# encoding: utf-8 -# -# Examples for loading existing pdfs. -# -require File.expand_path(File.join(File.dirname(__FILE__), - %w[.. example_helper])) - -Prawn::Example.generate("templates.pdf", :page_size => "FOLIO") do - - package "templates" do |p| - - p.example "full_template", :eval_source => false, :full_source => true - p.example "page_template" - - p.intro do - prose("NOTE: Templates are currently unmaintained and may be removed by Prawn 1.0!") - prose("Templates let you embed other PDF documents inside the current one. - - The examples show:") - - list( "How to load the whole content from another PDF", - "How to load single pages from another PDF" - ) - end - - end -end diff --git a/spec/template_spec.rb b/spec/template_spec_obsolete.rb similarity index 99% rename from spec/template_spec.rb rename to spec/template_spec_obsolete.rb index 9197f3fab..599338112 100644 --- a/spec/template_spec.rb +++ b/spec/template_spec_obsolete.rb @@ -1,4 +1,5 @@ -require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper") +require_relative "spec_helper" +require_relative "../lib/prawn/templates" describe "Document built from a template" do it "should have the same page count as the source document" do