Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 2af6fc97f027e0725ce72513ce6a3ccb3be6dc18 0 parents
Tim Riley timriley authored
Showing with 148 additions and 0 deletions.
  1. +20 −0 MIT-LICENSE
  2. +37 −0 README.md
  3. +23 −0 Rakefile
  4. +7 −0 init.rb
  5. +61 −0 lib/pdf_helper.rb
20 MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Tim Riley
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 README.md
@@ -0,0 +1,37 @@
+Saucerly
+========
+
+Saucerly provides PDF rendering for your Rails app using the Java-based [FlyingSaucer](https://xhtmlrenderer.dev.java.net/) library.
+
+It is based on [Princely](http://github.com/mbleigh/princely/). The benefit of Saucerly is that it provides competent XHTML to PDF rendering without the $4k PrinceXML pricetag.
+
+Example
+-------
+
+Rendering from a template:
+
+ class ExamplesController < ApplicationController::Base
+ def show
+ @document = Document.find(params[:id])
+
+ respond_to do |format|
+ format.html
+ format.pdf { render :pdf => 'file_name', :template => 'controller/action.pdf.haml', :layout => 'pdf' }
+ end
+ end
+ end
+
+Rendering from an inline string:
+
+ render :pdf => 'file_name', :inline => 'XHTML goes here'
+
+Installation
+------------
+
+1. Install [JRuby](http://jruby.org/)
+2. Register the flying_saucer gem dependency `config.gem 'flying_saucer'` to your `config/environment.rb`
+3. Install flying_saucer: `jruby -S rake gems:install`
+4. Install Saucerly: `jruby script/plugin install git://github.com/timriley/saucerly`
+5. Go!
+
+Copyright (c) 2009 Tim Riley & RentMonkey Pty Ltd, released under the MIT license
23 Rakefile
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the saucerly plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the saucerly plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'Saucerly'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
7 init.rb
@@ -0,0 +1,7 @@
+require 'java'
+require 'flying_saucer'
+
+require 'pdf_helper'
+
+Mime::Type.register 'application/pdf', :pdf
+ActionController::Base.send(:include, Saucerly::PdfHelper)
61 lib/pdf_helper.rb
@@ -0,0 +1,61 @@
+module Saucerly
+ module PdfHelper
+ def self.included(base)
+ base.class_eval do
+ alias_method_chain :render, :saucerly
+ end
+ end
+
+ def render_with_saucerly(options = nil, *args, &block)
+ if options.is_a?(Hash) && options.has_key?(:pdf)
+ options[:name] ||= options.delete(:pdf)
+ make_and_send_pdf(options.delete(:name), options)
+ else
+ render_without_saucerly(options, *args, &block)
+ end
+ end
+
+ private
+
+ def pdf_from_string(str)
+ # These lines are extracted from ITextRenderer's #setDocumentFromString, which doesn't
+ # seem to exist in the flying_saucer gem
+ is = org.xml.sax.InputSource.new(java.io.BufferedReader.new(java.io.StringReader.new(str)))
+ dom = org.xhtmlrenderer.resource.XMLResource.load(is).getDocument()
+
+ renderer = org.xhtmlrenderer.pdf.ITextRenderer.new
+ renderer.setDocument(dom, nil);
+ renderer.layout
+
+ output = java.io.ByteArrayOutputStream.new
+ renderer.createPDF(output, true)
+
+ String.from_java_bytes(output.to_byte_array)
+ end
+
+ def make_pdf(options = {})
+ html_string = if options[:inline]
+ render_to_string(:inline => options[:inline])
+ else
+ render_to_string(:template => options[:template], :layout => options[:layout])
+ end
+
+ # Make all paths relative, on disk paths...
+ html_string.gsub!(".com:/",".com/") # strip out bad attachment_fu URLs
+ html_string.gsub!( /src=["']+([^:]+?)["']/i ) { |m| "src=\"#{Rails.root}/public/" + $1 + '"' } # re-route absolute paths
+
+ # Remove asset ids on images with a regex
+ html_string.gsub!( /src=["'](\S+\?\d*)["']/i ) { |m| 'src="' + $1.split('?').first + '"' }
+ s
+ pdf_from_string(html_string)
+ end
+
+ def make_and_send_pdf(pdf_name, options = {})
+ send_data_options = {:filename => pdf_name + ".pdf", :type => 'application/pdf'}
+ disposition = options.delete(:disposition)
+ send_data_options[:disposition] = disposition if disposition
+
+ send_data(make_pdf(options), send_data_options)
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.