forked from prior/prawnto
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- broke out prawn and prawnto options - removed @prawn_document_options and instead using functions to dictate options - allowed option of dsl templates with locals - some testing as well
- Loading branch information
thorny_sun
committed
Aug 22, 2008
1 parent
45b01cf
commit 521ceb0
Showing
11 changed files
with
224 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
prawnto | ||
---------------- | ||
Prawnto | ||
======= | ||
|
||
a rails (2.1) plugin, providing templating abilities | ||
for generating pdf files leveraging the new kick-ass prawn library | ||
|
||
full documentation/demos at: http://cracklabs.com/prawnto | ||
|
||
|
||
|
||
|
||
Copyright (c) 2008 cracklabs.com, released under the MIT license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'rake' | ||
require 'rake/testtask' | ||
require 'rake/rdoctask' | ||
|
||
desc 'Default: run unit tests.' | ||
task :default => :test | ||
|
||
desc 'Test the prawnto plugin.' | ||
Rake::TestTask.new(:test) do |t| | ||
t.libs << 'lib' | ||
t.pattern = 'test/**/*_test.rb' | ||
t.verbose = true | ||
end | ||
|
||
desc 'Generate documentation for the prawnto plugin.' | ||
Rake::RDocTask.new(:rdoc) do |rdoc| | ||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = 'Prawnto' | ||
rdoc.options << '--line-numbers' << '--inline-source' | ||
rdoc.rdoc_files.include('README') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
require 'prawnto' | ||
|
||
Mime::Type.register "application/pdf", :pdf | ||
ActionView::Template.register_template_handler :prawn, Prawnto::Prawn | ||
ActionView::Template.register_template_handler :prawn, Prawnto::TemplateHandler | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,12 @@ | ||
require 'prawn' | ||
require 'prawnto/action_controller' | ||
require 'prawnto/template_handler' | ||
|
||
|
||
module Prawnto | ||
|
||
class Prawn < ActionView::TemplateHandler | ||
include ActionView::TemplateHandlers::Compilable | ||
|
||
# snips out source code from dummy method below (used by compile method) | ||
def self.template_setup_source | ||
@@template_setup_source ||= | ||
begin | ||
method = 'template_setup_source_container' | ||
regex_s = '\s*def\s' + method + '\s*\n(.*\n)\s*end\s*\#+\s*' + method | ||
source_regex = Regexp.new regex_s, Regexp::MULTILINE | ||
source_regex.match(File.read(__FILE__))[1] | ||
end | ||
end | ||
|
||
def self.line_offset | ||
@@line_offset ||= (self.template_setup_source.count("\n") + 1) | ||
end | ||
|
||
# incorporates template into a string to be compiled (using a proc) | ||
def compile(template) | ||
setup_source = Prawn::template_setup_source | ||
|
||
# what does following line do exactly? not sure but copied it from builder implementation -- no longer needed since only line with "controller" is flaky anyhow | ||
# setup_source.gsub!("controller","controller.response") if @view.send!(:controller).respond_to?(:response) | ||
|
||
setup_source + | ||
"pdf = Prawn::Document.new(@prawn_document_options)\n" + | ||
template.source + | ||
"\npdf.render\n" | ||
end | ||
|
||
|
||
# this is a dummy method to let me see code with editor's syntax goodness. | ||
# it is erased immediately afterwards | ||
# this method is never called, but instead the code is stripped out and pasted | ||
# as code to be run by the caller of compile method | ||
def template_setup_source_container | ||
@prawn_document_options ||= {} | ||
|
||
#TODO: check if this really makes sense-- kept around from railspdf, but maybe not needed? | ||
___pragma = 'no-cache' # underscores are an attempt to avoid name clashes with user's local view variables | ||
___cache_control = 'no-cache, must-revalidate' | ||
___pragma = ___cache_control = '' if request.env['HTTP_USER_AGENT'] =~ /msie/i #keep ie happy (from railspdf-- no personal knowledge of these issues) | ||
headers['Pragma'] ||= ___pragma | ||
headers['Cache-Control'] ||= ___cache_control | ||
|
||
# controller.content_type ||= Mime::PDF | ||
# for some reason above line is not working on subsequent requests for different pdfs, but the following does-- i have no clue? | ||
headers['Content-Type'] ||= 'application/pdf' | ||
|
||
attachment = @prawn_document_options.delete(:attachment) | ||
filename = @prawn_document_options.delete(:filename) | ||
attachment = attachment ? 'attachment' : 'inline' | ||
filename = filename ? "filename=#{filename}" : nil | ||
disposition = [attachment,filename].compact.join(';') | ||
|
||
headers["Content-Disposition"] ||= disposition if disposition.length > 0 | ||
|
||
#specify filename in controller otherwise will be inline | ||
#TODO: verify attachment/inline behavior | ||
#TODO: come up with solution for default naming (probably should just use railspdf way) | ||
|
||
end ### template_setup_source_container <--- keep comment there so i can use it to snip out this code easier | ||
remove_method :template_setup_source_container | ||
|
||
end | ||
# for now applying to all Controllers | ||
# however, could reduce footprint by letting user mixin (i.e. include) only into controllers that need it | ||
# but would does it really matter performance wise to include in a controller that doesn't need it? doubtful. | ||
class ActionController::Base | ||
include Prawnto::ActionController | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
module Prawnto | ||
module ActionController | ||
|
||
def self.included(base) | ||
base.extend ClassMethods | ||
base.before_filter :reset_prawnto_options | ||
end | ||
|
||
module ClassMethods | ||
def prawnto(options) | ||
prawn_options, prawnto_options = breakdown_prawnto_options options | ||
write_inheritable_hash(:prawn, prawn_options) | ||
write_inheritable_hash(:prawnto, prawnto_options) | ||
end | ||
|
||
private | ||
|
||
def breakdown_prawnto_options(options) | ||
prawnto_options = options.dup | ||
prawn_options = (prawnto_options.delete(:prawn) || {}).dup | ||
[prawn_options, prawnto_options] | ||
end | ||
end | ||
|
||
def prawnto(options) | ||
@prawnto_options = options | ||
end | ||
|
||
|
||
private | ||
|
||
def reset_prawnto_options | ||
@prawnto_options = nil | ||
end | ||
|
||
def compute_prawnto_options | ||
|
||
@prawnto_options ||= {} | ||
@prawnto_options[:prawn] ||= {} | ||
@prawnto_options[:prawn].merge!(self.class.read_inheritable_attribute(:prawn) || {}) {|k,o,n| o} | ||
@prawnto_options.merge!(self.class.read_inheritable_attribute(:prawnto) || {}) {|k,o,n| o} | ||
@prawnto_options | ||
end | ||
|
||
end | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
module Prawnto | ||
class TemplateHandler < ActionView::TemplateHandler | ||
include ActionView::TemplateHandlers::Compilable | ||
|
||
def self.line_offset | ||
# looks for spot where binding is called-- since that is where the template is ultimately evaluated -- and that is what will give us accurate line # reporting | ||
@@line_offset ||= template_wrapper_source.split(/^.*=\s*binding/)[0].count("\n") | ||
end | ||
|
||
def compile(template) | ||
self.class.template_wrapper_source.sub(/^\s*yield/, template.source) | ||
end | ||
|
||
private | ||
|
||
# this is a dummy method to let me see code with editor's syntax goodness. | ||
# it is erased immediately afterwards | ||
# this method is never called, but instead the code is stripped out and pasted | ||
# as code to be run by the caller of compile method | ||
def template_wrapper_source_container | ||
@prawnto_options = controller.send :compute_prawnto_options | ||
# underscores are an attempt to avoid name clashes with user's local view variables | ||
|
||
#TODO: check if this really makes sense-- kept around from railspdf, but maybe not needed? | ||
_pragma = 'no-cache' | ||
_cache_control = 'no-cache, must-revalidate' | ||
_pragma = _cache_control = '' if request.env['HTTP_USER_AGENT'] =~ /msie/i #keep ie happy (from railspdf-- no personal knowledge of these issues) | ||
response.headers['Pragma'] ||= _pragma | ||
response.headers['Cache-Control'] ||= _cache_control | ||
|
||
response.content_type = Mime::PDF | ||
|
||
_inline = @prawnto_options[:inline] ? 'inline' : 'attachment' | ||
_filename = @prawnto_options[:filename] ? "filename=#{_filename}" : nil | ||
_disposition = [_inline,_filename].compact.join(';') | ||
|
||
response.headers["Content-Disposition"] = _disposition if _disposition.length > 0 | ||
|
||
_binding = nil | ||
pdf = Prawn::Document.new(@prawnto_options[:prawn]) | ||
if _dsl = @prawnto_options[:dsl] | ||
_variable_transfer = if _dsl.kind_of?(Array) | ||
_dsl.map {|v| "#{v}=@#{v};"}.join('') | ||
elsif _dsl.kind_of?(Hash) | ||
_dsl.map {|k,v| "#{v}=@#{k};"}.join('') | ||
else | ||
"" | ||
end | ||
eval _variable_transfer | ||
pdf.instance_eval do | ||
_binding = binding; end; else; _binding = binding; #stuck together to keep binding captures on same line so line_offset is valid in both cases | ||
end | ||
|
||
_view = <<EOS | ||
yield | ||
EOS | ||
|
||
|
||
eval(_view,_binding) | ||
|
||
#TODO: verify attachment/inline behavior | ||
|
||
pdf.render | ||
end | ||
remove_method :template_wrapper_source_container | ||
|
||
|
||
# snips out source code from dummy method below (used by compile method) | ||
def self.template_wrapper_source | ||
@@template_wrapper_source ||= | ||
begin | ||
method = 'template_wrapper_source_container' | ||
regex_s = '(\s*)def\s' + method + '\s*\n(.*?\n)\1end' | ||
source_regex = Regexp.new regex_s, Regexp::MULTILINE | ||
source_regex.match(File.read(__FILE__))[2] | ||
end | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# desc "Explaining what the task does" | ||
# task :prawnto do | ||
# # Task goes here | ||
# end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
require 'rubygems' | ||
require 'action_controller' | ||
require 'action_view' | ||
|
||
require 'test/unit' | ||
require File.dirname(__FILE__) + '/../lib/prawnto' | ||
|
||
|
||
module Prawnto | ||
class ActionControllerTest < Test::Unit::TestCase | ||
|
||
def setup | ||
@controller_class = Class.new(::ActionController::Base) | ||
|
||
# for some reason using the following as a block in the preceding statement is somehow different? | ||
@controller_class.module_eval do | ||
prawnto :inline=>true, :prawn=>{:page_orientation=>:landscape} | ||
|
||
def test | ||
prawnto :inline=>false, :prawn=>{:page_size=>'A4'} | ||
end | ||
end | ||
end | ||
|
||
def test_inheritable_options | ||
assert_equal({:page_orientation=>:landscape}, @controller_class.read_inheritable_attribute(:prawn)) | ||
assert_equal({:inline=>true}, @controller_class.read_inheritable_attribute(:prawnto)) | ||
end | ||
|
||
def test_computed_options | ||
controller = @controller_class.new | ||
controller.test | ||
assert_equal({:inline=>false, :prawn=>{:page_orientation=>:landscape, :page_size=>'A4'}}, controller.send(:compute_prawnto_options)) | ||
end | ||
|
||
end | ||
|
||
class TemplateHandlerTest < Test::Unit::TestCase | ||
|
||
class ActionView; end | ||
class Template; def source; return 'SOURCE'; end; end | ||
|
||
def test_valid_source | ||
@template_handler = TemplateHandler.new(ActionView.new) | ||
source = @template_handler.compile(Template.new).split('SOURCE')[0] | ||
assert_equal TemplateHandler.line_offset, source.count("\n") | ||
assert TemplateHandler.line_offset > 10 | ||
end | ||
end | ||
end | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.