pdfkit_songrit 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.md +71 -0
- data/Rakefile +65 -0
- data/VERSION +1 -0
- data/bin/wkhtmltopdf-amd64 +0 -0
- data/bin/wkhtmltopdf-linux-i386-0-9-9 +0 -0
- data/bin/wkhtmltopdf-osx-i386-0-9-9 +0 -0
- data/bin/wkhtmltopdf-proxy +23 -0
- data/lib/pdfkit/middleware.rb +65 -0
- data/lib/pdfkit/pdfkit.rb +115 -0
- data/lib/pdfkit/source.rb +27 -0
- data/lib/pdfkit_songrit.rb +4 -0
- data/pdfkit_songrit.gemspec +73 -0
- data/spec/fixtures/example.css +1 -0
- data/spec/fixtures/example.html +5 -0
- data/spec/middleware_spec.rb +51 -0
- data/spec/pdfkit_spec.rb +130 -0
- data/spec/source_spec.rb +73 -0
- data/spec/spec_helper.rb +18 -0
- metadata +143 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 jdpace
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# PDFKit
|
2
|
+
|
3
|
+
Create PDFs using plain old HTML+CSS. Uses [wkhtmltopdf](http://github.com/antialize/wkhtmltopdf) on the backend which renders HTML using Webkit.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
1. Install wkhtmltopdf (optional)
|
8
|
+
** PDFKit comes bundled with wkhtmltopdf binaries for Linux i386 and OS X i386
|
9
|
+
** PDFKit defaults to user installed versions of wkhtmltopdf if found
|
10
|
+
** Installing wkhtmltopdf binary
|
11
|
+
*** Download the latest binary from http://code.google.com/p/wkhtmltopdf/downloads/list
|
12
|
+
*** Place the binary somewhere on your path (e.g /usr/local/bin)
|
13
|
+
2. Install PDFKit
|
14
|
+
|
15
|
+
$ gem install pdfkit
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
# PDFKit.new takes the HTML and any options for wkhtmltopdf
|
20
|
+
# run `wkhtmltopdf --extended-help` for a full list of options
|
21
|
+
kit = PDFKit.new(html, :page_size => 'Letter')
|
22
|
+
kit.stylesheets << '/path/to/css/file'
|
23
|
+
|
24
|
+
# Git an inline PDF
|
25
|
+
pdf = kit.to_pdf
|
26
|
+
|
27
|
+
# Save the PDF to a file
|
28
|
+
file = kit.to_file('/path/to/save/pdf')
|
29
|
+
|
30
|
+
# PDFKit.new can optionally accept a URL or a File.
|
31
|
+
# Stylesheets can not be added when source is provided as a URL of File.
|
32
|
+
kit = PDFKit.new('http://google.com')
|
33
|
+
kit = PDFKit.new(File.new('/path/to/html'))
|
34
|
+
|
35
|
+
## Middleware
|
36
|
+
|
37
|
+
PDFKit comes with a middleware that allows users to get a PDF view of any page on your site by appending .pdf to the URL.
|
38
|
+
|
39
|
+
### Middleware Setup
|
40
|
+
|
41
|
+
**Non-Rails Rack apps**
|
42
|
+
|
43
|
+
# in config.ru
|
44
|
+
require 'pdfkit'
|
45
|
+
use PDFKit::Middleware
|
46
|
+
|
47
|
+
**Rails apps**
|
48
|
+
|
49
|
+
# in application.rb(Rails3) or environment.rb(Rails2)
|
50
|
+
require 'pdfkit'
|
51
|
+
config.middleware.use PDFKit::Middleware
|
52
|
+
|
53
|
+
**With PDFKit options**
|
54
|
+
|
55
|
+
# options will be passed to PDFKit.new
|
56
|
+
config.middleware.use PDFKit::Middleware, :print_media_type => true
|
57
|
+
|
58
|
+
|
59
|
+
## Note on Patches/Pull Requests
|
60
|
+
|
61
|
+
* Fork the project.
|
62
|
+
* Make your feature addition or bug fix.
|
63
|
+
* Add tests for it. This is important so I don't break it in a
|
64
|
+
future version unintentionally.
|
65
|
+
* Commit, do not mess with rakefile, version, or history.
|
66
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
67
|
+
* Send me a pull request. Bonus points for topic branches.
|
68
|
+
|
69
|
+
## Copyright
|
70
|
+
|
71
|
+
Copyright (c) 2010 Jared Pace. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "pdfkit"
|
8
|
+
gem.summary = %Q{HTML+CSS -> PDF}
|
9
|
+
gem.description = %Q{Uses wkhtmltopdf to create PDFs using HTML}
|
10
|
+
gem.email = "jared@codewordstudios.com"
|
11
|
+
gem.homepage = "http://github.com/jdpace/PDFKit"
|
12
|
+
gem.authors = ["jdpace"]
|
13
|
+
gem.add_development_dependency "rspec", "~> 2.0.0.beta.8"
|
14
|
+
gem.add_development_dependency "rspec-core", "~> 2.0.0.beta.8"
|
15
|
+
gem.add_development_dependency 'mocha'
|
16
|
+
gem.files = [
|
17
|
+
".document",
|
18
|
+
".gitignore",
|
19
|
+
"LICENSE",
|
20
|
+
"README.md",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"bin/wkhtmltopdf-linux-i386-0-9-9",
|
24
|
+
"bin/wkhtmltopdf-osx-i386-0-9-9",
|
25
|
+
"bin/wkhtmltopdf-proxy",
|
26
|
+
"lib/pdfkit.rb",
|
27
|
+
"lib/pdfkit/middleware.rb",
|
28
|
+
"lib/pdfkit/pdfkit.rb",
|
29
|
+
"lib/pdfkit/source.rb",
|
30
|
+
"pdfkit.gemspec",
|
31
|
+
"spec/pdfkit_spec.rb",
|
32
|
+
"spec/source_spec.rb",
|
33
|
+
"spec/fixtures/example.css",
|
34
|
+
"spec/fixtures/example.html",
|
35
|
+
"spec/spec.opts",
|
36
|
+
"spec/spec_helper.rb"
|
37
|
+
]
|
38
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
39
|
+
end
|
40
|
+
Jeweler::GemcutterTasks.new
|
41
|
+
rescue LoadError
|
42
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'rspec/core/rake_task'
|
46
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
47
|
+
end
|
48
|
+
|
49
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
50
|
+
spec.rcov = true
|
51
|
+
end
|
52
|
+
|
53
|
+
task :spec => :check_dependencies
|
54
|
+
|
55
|
+
task :default => :spec
|
56
|
+
|
57
|
+
require 'rake/rdoctask'
|
58
|
+
Rake::RDocTask.new do |rdoc|
|
59
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
60
|
+
|
61
|
+
rdoc.rdoc_dir = 'rdoc'
|
62
|
+
rdoc.title = "PDFKit #{version}"
|
63
|
+
rdoc.rdoc_files.include('README*')
|
64
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
65
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.3
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
executable = `which wkhtmltopdf`.chomp
|
4
|
+
|
5
|
+
if executable.empty?
|
6
|
+
|
7
|
+
binary = case RUBY_PLATFORM
|
8
|
+
when /x86_64-linux/
|
9
|
+
'wkhtmltopdf-amd64'
|
10
|
+
when /linux/
|
11
|
+
'wkhtmltopdf-linux-i386-0-9-9'
|
12
|
+
when /darwin/
|
13
|
+
'wkhtmltopdf-osx-i386-0-9-9'
|
14
|
+
else
|
15
|
+
raise "No bundled binaries found for your system. Please install wkhtmltopdf."
|
16
|
+
end
|
17
|
+
executable = File.join(File.dirname(__FILE__), binary)
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
arguments = $*.map { |arg| arg.include?(' ') ? %Q("#{arg}") : arg }
|
22
|
+
|
23
|
+
system(executable + " " + arguments.join(" "))
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class PDFKit
|
2
|
+
|
3
|
+
class Middleware
|
4
|
+
|
5
|
+
def initialize(app, options = {})
|
6
|
+
@app = app
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
@render_pdf = false
|
12
|
+
set_request_to_render_as_pdf(env) if env['PATH_INFO'].match(/\.pdf$/)
|
13
|
+
|
14
|
+
status, headers, response = @app.call(env)
|
15
|
+
|
16
|
+
request = Rack::Request.new(env)
|
17
|
+
if @render_pdf && headers['Content-Type'] =~ /text\/html|application\/xhtml\+xml/
|
18
|
+
body = response.body
|
19
|
+
|
20
|
+
body = translate_paths(body, env)
|
21
|
+
|
22
|
+
pdf = PDFKit.new(body, @options)
|
23
|
+
body = pdf.to_pdf
|
24
|
+
|
25
|
+
# Do not cache PDFs
|
26
|
+
puts "DELETING CACHING"
|
27
|
+
headers.delete('ETag')
|
28
|
+
headers.delete('Cache-Control')
|
29
|
+
|
30
|
+
headers["Content-Length"] = body.bytes.to_a.size.to_s
|
31
|
+
headers["Content-Type"] = "application/pdf"
|
32
|
+
|
33
|
+
response = [body]
|
34
|
+
end
|
35
|
+
|
36
|
+
[status, headers, response]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Change relative paths to absolute
|
42
|
+
def translate_paths(body, env)
|
43
|
+
# Host with protocol
|
44
|
+
root = env['rack.url_scheme'] + "://" + env['HTTP_HOST'] + "/"
|
45
|
+
|
46
|
+
body.gsub!(/(href|src)=['"]\/([^\"']*|[^"']*)['"]/,'\1="'+root+'\2"')
|
47
|
+
|
48
|
+
return body
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_request_to_render_as_pdf(env)
|
52
|
+
@render_pdf = true
|
53
|
+
puts "Setting PDF mode"
|
54
|
+
|
55
|
+
path = Pathname(env['PATH_INFO'])
|
56
|
+
['PATH_INFO','REQUEST_URI'].each { |e| env[e] = path.to_s.sub(/#{path.extname}$/,'') } if path.extname == '.pdf'
|
57
|
+
env['HTTP_ACCEPT'] = concat(env['HTTP_ACCEPT'], Rack::Mime.mime_type('.html'))
|
58
|
+
end
|
59
|
+
|
60
|
+
def concat(accepts, type)
|
61
|
+
(accepts || '').split(',').unshift(type).compact.join(',')
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class PDFKit
|
2
|
+
|
3
|
+
class NoExecutableError < StandardError
|
4
|
+
def initialize
|
5
|
+
super('Could not locate wkhtmltopdf-proxy executable')
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ImproperSourceError < StandardError
|
10
|
+
def initialize(msg)
|
11
|
+
super("Improper Source: #{msg}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :source, :stylesheets
|
16
|
+
attr_reader :options
|
17
|
+
|
18
|
+
def initialize(url_file_or_html, options = {})
|
19
|
+
@source = Source.new(url_file_or_html)
|
20
|
+
|
21
|
+
@stylesheets = []
|
22
|
+
|
23
|
+
default_options = {
|
24
|
+
:disable_smart_shrinking => true,
|
25
|
+
:page_size => 'Letter',
|
26
|
+
:margin_top => '0.75in',
|
27
|
+
:margin_right => '0.75in',
|
28
|
+
:margin_bottom => '0.75in',
|
29
|
+
:margin_left => '0.75in'
|
30
|
+
}
|
31
|
+
@wkhtmltopdf= options[:exe] if options[:exe]
|
32
|
+
options.delete(:exe)
|
33
|
+
@options = normalize_options(default_options.merge(options))
|
34
|
+
|
35
|
+
raise NoExecutableError.new if wkhtmltopdf.nil? || wkhtmltopdf == ''
|
36
|
+
end
|
37
|
+
|
38
|
+
def command
|
39
|
+
args = [wkhtmltopdf]
|
40
|
+
args += @options.to_a.flatten.compact
|
41
|
+
args << '--quiet'
|
42
|
+
|
43
|
+
if @source.html?
|
44
|
+
args << '-' # Get HTML from stdin
|
45
|
+
else
|
46
|
+
args << @source.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
args << '-' # Read PDF from stdout
|
50
|
+
args.join(' ')
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_pdf
|
54
|
+
append_stylesheets
|
55
|
+
|
56
|
+
pdf = IO.popen(command, "w+")
|
57
|
+
pdf.puts(@source.to_s) if @source.html?
|
58
|
+
pdf.close_write
|
59
|
+
result = pdf.gets(nil)
|
60
|
+
pdf.close_read
|
61
|
+
return result
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_file(path)
|
65
|
+
File.open(path,'w') {|file| file << self.to_pdf}
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
def wkhtmltopdf
|
71
|
+
@wkhtmltopdf ||= `which wkhtmltopdf-proxy`.chomp
|
72
|
+
end
|
73
|
+
|
74
|
+
def style_tag_for(stylesheet)
|
75
|
+
"<style>#{File.read(stylesheet)}</style>"
|
76
|
+
end
|
77
|
+
|
78
|
+
def append_stylesheets
|
79
|
+
raise ImproperSourceError.new('Stylesheets may only be added to an HTML source') if stylesheets.any? && !@source.html?
|
80
|
+
|
81
|
+
stylesheets.each do |stylesheet|
|
82
|
+
if @source.to_s.match(/<\/head>/)
|
83
|
+
@source.to_s.gsub!(/(<\/head>)/, style_tag_for(stylesheet)+'\1')
|
84
|
+
else
|
85
|
+
@source.to_s.insert(0, style_tag_for(stylesheet))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def normalize_options(options)
|
91
|
+
normalized_options = {}
|
92
|
+
options.each do |key, value|
|
93
|
+
next if !value
|
94
|
+
normalized_key = "--#{normalize_arg key}"
|
95
|
+
normalized_options[normalized_key] = normalize_value(value)
|
96
|
+
end
|
97
|
+
normalized_options
|
98
|
+
end
|
99
|
+
|
100
|
+
def normalize_arg(arg)
|
101
|
+
arg.to_s.downcase.gsub(/[^a-z0-9]/,'-')
|
102
|
+
end
|
103
|
+
|
104
|
+
def normalize_value(value)
|
105
|
+
case value
|
106
|
+
when TrueClass
|
107
|
+
nil
|
108
|
+
when String
|
109
|
+
value.match(/\s/) ? "\"#{value}\"" : value
|
110
|
+
else
|
111
|
+
value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class PDFKit
|
2
|
+
|
3
|
+
class Source
|
4
|
+
|
5
|
+
def initialize(url_file_or_html)
|
6
|
+
@source = url_file_or_html
|
7
|
+
end
|
8
|
+
|
9
|
+
def url?
|
10
|
+
@source.is_a?(String) && @source.match(/^http/)
|
11
|
+
end
|
12
|
+
|
13
|
+
def file?
|
14
|
+
@source.kind_of?(File)
|
15
|
+
end
|
16
|
+
|
17
|
+
def html?
|
18
|
+
!(url? || file?)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
file? ? @source.path : @source
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{pdfkit_songrit}
|
8
|
+
s.version = "0.3.4"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["jdpace/songrit"]
|
12
|
+
s.date = %q{2010-07-13}
|
13
|
+
s.description = %q{Uses wkhtmltopdf to create PDFs using HTML, add :exe option}
|
14
|
+
s.email = %q{jared@codewordstudios.com}
|
15
|
+
s.executables = ["wkhtmltopdf-amd64", "wkhtmltopdf-linux-i386-0-9-9", "wkhtmltopdf-osx-i386-0-9-9", "wkhtmltopdf-proxy"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE",
|
18
|
+
"README.md"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".document",
|
22
|
+
".gitignore",
|
23
|
+
"LICENSE",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"bin/wkhtmltopdf-amd64",
|
28
|
+
"bin/wkhtmltopdf-linux-i386-0-9-9",
|
29
|
+
"bin/wkhtmltopdf-osx-i386-0-9-9",
|
30
|
+
"bin/wkhtmltopdf-proxy",
|
31
|
+
"lib/pdfkit_songrit.rb",
|
32
|
+
"lib/pdfkit/middleware.rb",
|
33
|
+
"lib/pdfkit/pdfkit.rb",
|
34
|
+
"lib/pdfkit/source.rb",
|
35
|
+
"pdfkit_songrit.gemspec",
|
36
|
+
"spec/fixtures/example.css",
|
37
|
+
"spec/fixtures/example.html",
|
38
|
+
"spec/pdfkit_spec.rb",
|
39
|
+
"spec/source_spec.rb",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/jdpace/PDFKit}
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.3.7}
|
46
|
+
s.summary = %q{HTML+CSS -> PDF}
|
47
|
+
s.test_files = [
|
48
|
+
"spec/middleware_spec.rb",
|
49
|
+
"spec/pdfkit_spec.rb",
|
50
|
+
"spec/source_spec.rb",
|
51
|
+
"spec/spec_helper.rb"
|
52
|
+
]
|
53
|
+
|
54
|
+
if s.respond_to? :specification_version then
|
55
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
56
|
+
s.specification_version = 3
|
57
|
+
|
58
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
|
60
|
+
s.add_development_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
|
61
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
62
|
+
else
|
63
|
+
s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
|
64
|
+
s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
|
65
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
|
69
|
+
s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
|
70
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
body { font-size: 20px; }
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PDFKit::Middleware do
|
4
|
+
describe "#translate_paths" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@pdf = PDFKit::Middleware.new({})
|
8
|
+
@env = {'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com'}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should correctly parse relative url with single quotes" do
|
12
|
+
@body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src='/test.png' /></body></html>}
|
13
|
+
body = @pdf.send :translate_paths, @body, @env
|
14
|
+
body.should == "<html><head><link href=\"http://example.com/stylesheets/application.css\" media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.com/test.png\" /></body></html>"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should correctly parse relative url with double quotes" do
|
18
|
+
@body = %{<link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />}
|
19
|
+
body = @pdf.send :translate_paths, @body, @env
|
20
|
+
body.should == "<link href=\"http://example.com/stylesheets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return the body even if there are no valid substitutions found" do
|
24
|
+
@body = "NO MATCH"
|
25
|
+
body = @pdf.send :translate_paths, @body, @env
|
26
|
+
body.should == "NO MATCH"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#set_request_to_render_as_pdf" do
|
32
|
+
|
33
|
+
before do
|
34
|
+
@pdf = PDFKit::Middleware.new({})
|
35
|
+
|
36
|
+
@pdf_env = {'PATH_INFO' => Pathname.new("file.pdf"), 'REQUEST_URI' => Pathname.new("file.pdf")}
|
37
|
+
@non_pdf_env = {'PATH_INFO' => Pathname.new("file.txt"), 'REQUEST_URI' => Pathname.new("file.txt")}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should replace .pdf in PATH_INFO when the extname is .pdf" do
|
41
|
+
@pdf.send :set_request_to_render_as_pdf, @pdf_env
|
42
|
+
@pdf_env['PATH_INFO'].should == "file"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should replace .pdf in REQUEST_URI when the extname is .pdf" do
|
46
|
+
@pdf.send :set_request_to_render_as_pdf, @pdf_env
|
47
|
+
@pdf_env['REQUEST_URI'].should == "file"
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/spec/pdfkit_spec.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PDFKit do
|
4
|
+
|
5
|
+
context "initialization" do
|
6
|
+
it "should accept HTML as the source" do
|
7
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
8
|
+
pdfkit.source.should be_html
|
9
|
+
pdfkit.source.to_s.should == '<h1>Oh Hai</h1>'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should accept a URL as the source" do
|
13
|
+
pdfkit = PDFKit.new('http://google.com')
|
14
|
+
pdfkit.source.should be_url
|
15
|
+
pdfkit.source.to_s.should == 'http://google.com'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should accept a File as the source" do
|
19
|
+
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
20
|
+
pdfkit = PDFKit.new(File.new(file_path))
|
21
|
+
pdfkit.source.should be_file
|
22
|
+
pdfkit.source.to_s.should == file_path
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should parse the options into a cmd line friedly format" do
|
26
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
27
|
+
pdfkit.options.should have_key('--page-size')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should provide default options" do
|
31
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
32
|
+
['--disable-smart-shrinking', '--margin-top', '--margin-right', '--margin-bottom', '--margin-left'].each do |option|
|
33
|
+
pdfkit.options.should have_key(option)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not have any stylesheedt by default" do
|
38
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
39
|
+
pdfkit.stylesheets.should be_empty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "command" do
|
44
|
+
it "should contstruct the correct command" do
|
45
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12)
|
46
|
+
pdfkit.command.should include('wkhtmltopdf')
|
47
|
+
pdfkit.command.should include('--page-size Letter')
|
48
|
+
pdfkit.command.should include('--toc-l1-font-size 12')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "will not include default options it is told to omit" do
|
52
|
+
pdfkit = PDFKit.new('html')
|
53
|
+
pdfkit.command.should include('--disable-smart-shrinking')
|
54
|
+
pdfkit = PDFKit.new('html', :disable_smart_shrinking => false)
|
55
|
+
pdfkit.command.should_not include('--disable-smart-shrinking')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should encapsulate string arguments in quotes" do
|
59
|
+
pdfkit = PDFKit.new('html', :header_center => "foo [page]")
|
60
|
+
pdfkit.command.should include('--header-center "foo [page]"')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "read the source from stdin if it is html" do
|
64
|
+
pdfkit = PDFKit.new('html')
|
65
|
+
pdfkit.command.should match(/ - -$/)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "specify the URL to the source if it is a url" do
|
69
|
+
pdfkit = PDFKit.new('http://google.com')
|
70
|
+
pdfkit.command.should match(/ http:\/\/google\.com -$/)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should specify the path to the source if it is a file" do
|
74
|
+
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
75
|
+
pdfkit = PDFKit.new(File.new(file_path))
|
76
|
+
pdfkit.command.should match(/ #{file_path} -$/)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "#to_pdf" do
|
81
|
+
it "should generate a PDF of the HTML" do
|
82
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
83
|
+
pdf = pdfkit.to_pdf
|
84
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should have the stylesheet added to the head if it has one" do
|
88
|
+
pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
|
89
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
90
|
+
pdfkit.stylesheets << css
|
91
|
+
pdfkit.to_pdf
|
92
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style>")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should prepend style tags if the HTML doesn't have a head tag" do
|
96
|
+
pdfkit = PDFKit.new("<html><body>Hai!</body></html>")
|
97
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
98
|
+
pdfkit.stylesheets << css
|
99
|
+
pdfkit.to_pdf
|
100
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style><html>")
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should throw an error if the source is not html and stylesheets have been added" do
|
104
|
+
pdfkit = PDFKit.new('http://google.com')
|
105
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
106
|
+
pdfkit.stylesheets << css
|
107
|
+
lambda { pdfkit.to_pdf }.should raise_error(PDFKit::ImproperSourceError)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "#to_file" do
|
112
|
+
before do
|
113
|
+
@file_path = File.join(SPEC_ROOT,'fixtures','test.pdf')
|
114
|
+
File.delete(@file_path) if File.exist?(@file_path)
|
115
|
+
end
|
116
|
+
|
117
|
+
after do
|
118
|
+
File.delete(@file_path)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should create a file with the PDF as content" do
|
122
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
123
|
+
pdfkit.expects(:to_pdf).returns('PDF')
|
124
|
+
file = pdfkit.to_file(@file_path)
|
125
|
+
file.should be_instance_of(File)
|
126
|
+
File.read(file.path).should == 'PDF'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
data/spec/source_spec.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PDFKit::Source do
|
4
|
+
|
5
|
+
describe "#url?" do
|
6
|
+
it "should return true if passed a url like string" do
|
7
|
+
source = PDFKit::Source.new('http://google.com')
|
8
|
+
source.should be_url
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return false if passed a file" do
|
12
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
13
|
+
source.should_not be_url
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return false if passed HTML" do
|
17
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
18
|
+
source.should_not be_url
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#file?" do
|
23
|
+
it "should return true if passed a file" do
|
24
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
25
|
+
source.should be_file
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return false if passed a url like string" do
|
29
|
+
source = PDFKit::Source.new('http://google.com')
|
30
|
+
source.should_not be_file
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return false if passed HTML" do
|
34
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
35
|
+
source.should_not be_file
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#html?" do
|
40
|
+
it "should return true if passed HTML" do
|
41
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
42
|
+
source.should be_html
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return false if passed a file" do
|
46
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
47
|
+
source.should_not be_html
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return false if passed a url like string" do
|
51
|
+
source = PDFKit::Source.new('http://google.com')
|
52
|
+
source.should_not be_html
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#to_s" do
|
57
|
+
it "should return the HTML if passed HTML" do
|
58
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
59
|
+
source.to_s.should == '<blink>Oh Hai!</blink>'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return a path if passed a file" do
|
63
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
64
|
+
source.to_s.should == __FILE__
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return the url if passed a url like string" do
|
68
|
+
source = PDFKit::Source.new('http://google.com')
|
69
|
+
source.to_s.should == 'http://google.com'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
SPEC_ROOT = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(SPEC_ROOT)
|
3
|
+
$LOAD_PATH.unshift(File.join(SPEC_ROOT, '..', 'lib'))
|
4
|
+
require 'pdfkit'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rspec/autorun'
|
7
|
+
require 'mocha'
|
8
|
+
require 'rack'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
config.before do
|
13
|
+
PDFKit.any_instance.stubs(:wkhtmltopdf).returns(
|
14
|
+
File.join(SPEC_ROOT,'..','bin','wkhtmltopdf-proxy')
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pdfkit_songrit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 4
|
10
|
+
version: 0.3.4
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- jdpace/songrit
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-13 00:00:00 +07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 62196467
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
- beta
|
35
|
+
- 8
|
36
|
+
version: 2.0.0.beta.8
|
37
|
+
type: :development
|
38
|
+
version_requirements: *id001
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: rspec-core
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 62196467
|
48
|
+
segments:
|
49
|
+
- 2
|
50
|
+
- 0
|
51
|
+
- 0
|
52
|
+
- beta
|
53
|
+
- 8
|
54
|
+
version: 2.0.0.beta.8
|
55
|
+
type: :development
|
56
|
+
version_requirements: *id002
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: mocha
|
59
|
+
prerelease: false
|
60
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id003
|
71
|
+
description: Uses wkhtmltopdf to create PDFs using HTML, add :exe option
|
72
|
+
email: jared@codewordstudios.com
|
73
|
+
executables:
|
74
|
+
- wkhtmltopdf-amd64
|
75
|
+
- wkhtmltopdf-linux-i386-0-9-9
|
76
|
+
- wkhtmltopdf-osx-i386-0-9-9
|
77
|
+
- wkhtmltopdf-proxy
|
78
|
+
extensions: []
|
79
|
+
|
80
|
+
extra_rdoc_files:
|
81
|
+
- LICENSE
|
82
|
+
- README.md
|
83
|
+
files:
|
84
|
+
- .document
|
85
|
+
- .gitignore
|
86
|
+
- LICENSE
|
87
|
+
- README.md
|
88
|
+
- Rakefile
|
89
|
+
- VERSION
|
90
|
+
- bin/wkhtmltopdf-amd64
|
91
|
+
- bin/wkhtmltopdf-linux-i386-0-9-9
|
92
|
+
- bin/wkhtmltopdf-osx-i386-0-9-9
|
93
|
+
- bin/wkhtmltopdf-proxy
|
94
|
+
- lib/pdfkit_songrit.rb
|
95
|
+
- lib/pdfkit/middleware.rb
|
96
|
+
- lib/pdfkit/pdfkit.rb
|
97
|
+
- lib/pdfkit/source.rb
|
98
|
+
- pdfkit_songrit.gemspec
|
99
|
+
- spec/fixtures/example.css
|
100
|
+
- spec/fixtures/example.html
|
101
|
+
- spec/pdfkit_spec.rb
|
102
|
+
- spec/source_spec.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
- spec/middleware_spec.rb
|
105
|
+
has_rdoc: true
|
106
|
+
homepage: http://github.com/jdpace/PDFKit
|
107
|
+
licenses: []
|
108
|
+
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options:
|
111
|
+
- --charset=UTF-8
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
version: "0"
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
hash: 3
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
132
|
+
requirements: []
|
133
|
+
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 1.3.7
|
136
|
+
signing_key:
|
137
|
+
specification_version: 3
|
138
|
+
summary: HTML+CSS -> PDF
|
139
|
+
test_files:
|
140
|
+
- spec/middleware_spec.rb
|
141
|
+
- spec/pdfkit_spec.rb
|
142
|
+
- spec/source_spec.rb
|
143
|
+
- spec/spec_helper.rb
|