pdfkit 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pdfkit might be problematic. Click here for more details.
- data/.rspec +1 -0
- data/README.md +26 -12
- data/Rakefile +8 -23
- data/VERSION +1 -1
- data/bin/pdfkit +68 -0
- data/lib/pdfkit.rb +2 -1
- data/lib/pdfkit/configuration.rb +32 -0
- data/lib/pdfkit/middleware.rb +4 -3
- data/lib/pdfkit/pdfkit.rb +36 -12
- data/pdfkit.gemspec +16 -7
- data/spec/middleware_spec.rb +27 -0
- data/spec/pdfkit_spec.rb +30 -7
- data/spec/spec_helper.rb +1 -0
- metadata +20 -16
- data/bin/wkhtmltopdf-linux-i386-0-9-9 +0 -0
- data/bin/wkhtmltopdf-osx-i386-0-9-9 +0 -0
- data/bin/wkhtmltopdf-proxy +0 -21
- data/spec/PDFKit_spec.rb +0 -130
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/README.md
CHANGED
@@ -2,18 +2,18 @@
|
|
2
2
|
|
3
3
|
Create PDFs using plain old HTML+CSS. Uses [wkhtmltopdf](http://github.com/antialize/wkhtmltopdf) on the backend which renders HTML using Webkit.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Install
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
### PDFKit
|
8
|
+
|
9
|
+
gem install pdfkit
|
10
|
+
|
11
|
+
### wkhtmltopdf
|
12
|
+
* **Automatic**: `sudo pdfkit --install-wkhtmltopdf`
|
13
|
+
install latest version into /usr/local/bin
|
14
|
+
(overwrite defaults with e.g. ARCHITECTURE=amd64 TO=/home/foo/bin)
|
15
|
+
* By hand: http://code.google.com/p/wkhtmltopdf/downloads/list
|
14
16
|
|
15
|
-
$ gem install pdfkit
|
16
|
-
|
17
17
|
## Usage
|
18
18
|
|
19
19
|
# PDFKit.new takes the HTML and any options for wkhtmltopdf
|
@@ -31,10 +31,22 @@ Create PDFs using plain old HTML+CSS. Uses [wkhtmltopdf](http://github.com/antia
|
|
31
31
|
# Stylesheets can not be added when source is provided as a URL of File.
|
32
32
|
kit = PDFKit.new('http://google.com')
|
33
33
|
kit = PDFKit.new(File.new('/path/to/html'))
|
34
|
-
|
34
|
+
|
35
|
+
# Add any kind of option through meta tags
|
36
|
+
PDFKit.new('<html><head><meta name="pdfkit-page-size" content="Letter")
|
37
|
+
|
38
|
+
## Configuration
|
39
|
+
|
40
|
+
If you're on Windows or you installed wkhtmltopdf by hand to a location other than /usr/local/bin you will need to tell PDFKit where the binary is. You can configure PDFKit like so:
|
41
|
+
|
42
|
+
# config/initializers/pdfkit.rb
|
43
|
+
PDFKit.configure do |config|
|
44
|
+
config.wkhtmltopdf = '/path/to/wkhtmltopdf'
|
45
|
+
end
|
46
|
+
|
35
47
|
## Middleware
|
36
48
|
|
37
|
-
PDFKit comes with a middleware that allows users to
|
49
|
+
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
50
|
|
39
51
|
### Middleware Setup
|
40
52
|
|
@@ -55,6 +67,8 @@ PDFKit comes with a middleware that allows users to visit any to get a PDF view
|
|
55
67
|
# options will be passed to PDFKit.new
|
56
68
|
config.middleware.use PDFKit::Middleware, :print_media_type => true
|
57
69
|
|
70
|
+
## TODO
|
71
|
+
- add amd64 support in --install-wkhtmltopdf
|
58
72
|
|
59
73
|
## Note on Patches/Pull Requests
|
60
74
|
|
data/Rakefile
CHANGED
@@ -13,29 +13,14 @@ begin
|
|
13
13
|
gem.add_development_dependency "rspec", "~> 2.0.0.beta.8"
|
14
14
|
gem.add_development_dependency "rspec-core", "~> 2.0.0.beta.8"
|
15
15
|
gem.add_development_dependency 'mocha'
|
16
|
-
gem.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
16
|
+
gem.post_install_message = <<-POST_INSTALL_MESSAGE
|
17
|
+
#{'*'*50}
|
18
|
+
|
19
|
+
Run sudo pdfkit --install-wkhtmltopdf to install wkhtmltopdf binaries.
|
20
|
+
(run pdfkit --help to see more options)
|
21
|
+
|
22
|
+
#{'*'*50}
|
23
|
+
POST_INSTALL_MESSAGE
|
39
24
|
end
|
40
25
|
Jeweler::GemcutterTasks.new
|
41
26
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/bin/pdfkit
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'optparse'
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'pdfkit/configuration'
|
7
|
+
|
8
|
+
def detect_architecture
|
9
|
+
case Config::CONFIG['host_os']
|
10
|
+
when /x86_64-linux/i
|
11
|
+
'amd64'
|
12
|
+
when /linux/i
|
13
|
+
'i386'
|
14
|
+
when /darwin/i
|
15
|
+
'OS-X.i368'
|
16
|
+
else
|
17
|
+
raise "No binaries found for your system. Please install wkhtmltopdf by hand."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def cleanup(install_to)
|
22
|
+
`rm -rf wkhtmltopdf*`
|
23
|
+
`rm #{install_to}`
|
24
|
+
end
|
25
|
+
|
26
|
+
def download_wkhtmltopdf(arch)
|
27
|
+
page = open("http://code.google.com/p/wkhtmltopdf/downloads/list").read
|
28
|
+
download = page.match(/href=".*name=(.*wkhtmltopdf-.*#{arch}.*?)&/) || raise("File not found..")
|
29
|
+
download = download[1]
|
30
|
+
url = "http://wkhtmltopdf.googlecode.com/files/#{download}"
|
31
|
+
puts "Downloading #{download} from #{url}"
|
32
|
+
|
33
|
+
`curl #{url} > #{download}`
|
34
|
+
download
|
35
|
+
end
|
36
|
+
|
37
|
+
def install(download, arch, install_to)
|
38
|
+
puts "Installing #{download} to #{install_to}"
|
39
|
+
if download =~ /.tar.bz2$/
|
40
|
+
`tar xjvf #{download}`
|
41
|
+
`mv wkhtmltopdf-#{arch} #{install_to}`
|
42
|
+
else
|
43
|
+
`mv #{download} #{install_to}`
|
44
|
+
end
|
45
|
+
`sudo chmod +x #{install_to}`
|
46
|
+
end
|
47
|
+
|
48
|
+
OptionParser.new do |parser|
|
49
|
+
parser.banner = "PDFKit\n\nOptions are:"
|
50
|
+
|
51
|
+
parser.on("--install-wkhtmltopdf", "Install wkhtmltopdf binaries (TO=/usr/local/bin ARCHITECTURE=i386)") do
|
52
|
+
architecture = ENV['ARCHITECTURE'] || detect_architecture
|
53
|
+
install_to = ENV['TO'] || PDFKit.configuration.wkhtmltopdf
|
54
|
+
|
55
|
+
Dir.chdir '/tmp'
|
56
|
+
|
57
|
+
cleanup(install_to)
|
58
|
+
download = download_wkhtmltopdf(architecture)
|
59
|
+
install(download, architecture, install_to)
|
60
|
+
end
|
61
|
+
|
62
|
+
parser.on("--version", "Show Version.") do
|
63
|
+
root = File.dirname(File.dirname(__FILE__))
|
64
|
+
puts File.read(File.join(root, 'VERSION'))
|
65
|
+
end
|
66
|
+
|
67
|
+
parser.on("-h", "--help", "Show this.") { puts parser; exit }
|
68
|
+
end.parse!
|
data/lib/pdfkit.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
class PDFKit
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :meta_tag_prefix, :wkhtmltopdf
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@meta_tag_prefix = 'pdfkit-'
|
7
|
+
@wkhtmltopdf = '/usr/local/bin/wkhtmltopdf'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :configuration
|
13
|
+
end
|
14
|
+
|
15
|
+
# Configure PDFKit someplace sensible,
|
16
|
+
# like config/initializers/pdfkit.rb
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# PDFKit.configure do |config|
|
20
|
+
# config.wkhtmltopdf = '/usr/bin/wkhtmltopdf'
|
21
|
+
# end
|
22
|
+
|
23
|
+
def self.configuration
|
24
|
+
@configuration ||= Configuration.new
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def self.configure
|
29
|
+
self.configuration
|
30
|
+
yield(configuration)
|
31
|
+
end
|
32
|
+
end
|
data/lib/pdfkit/middleware.rb
CHANGED
@@ -44,14 +44,15 @@ class PDFKit
|
|
44
44
|
root = env['rack.url_scheme'] + "://" + env['HTTP_HOST'] + "/"
|
45
45
|
|
46
46
|
body.gsub!(/(href|src)=['"]\/([^\"']*|[^"']*)['"]/,'\1="'+root+'\2"')
|
47
|
+
|
48
|
+
return body
|
47
49
|
end
|
48
50
|
|
49
51
|
def set_request_to_render_as_pdf(env)
|
50
52
|
@render_pdf = true
|
51
|
-
|
52
|
-
|
53
|
+
|
53
54
|
path = Pathname(env['PATH_INFO'])
|
54
|
-
|
55
|
+
['PATH_INFO','REQUEST_URI'].each { |e| env[e] = path.to_s.sub(/#{path.extname}$/,'') } if path.extname == '.pdf'
|
55
56
|
env['HTTP_ACCEPT'] = concat(env['HTTP_ACCEPT'], Rack::Mime.mime_type('.html'))
|
56
57
|
end
|
57
58
|
|
data/lib/pdfkit/pdfkit.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
class PDFKit
|
2
|
-
|
2
|
+
|
3
3
|
class NoExecutableError < StandardError
|
4
4
|
def initialize
|
5
|
-
|
5
|
+
msg = "No wkhtmltopdf executable found at #{PDFKit.configuration.wkhtmltopdf}\n"
|
6
|
+
msg << ">> Install wkhtmltopdf by hand or try running `pdfkit --install-wkhtmltopdf`"
|
7
|
+
super(msg)
|
6
8
|
end
|
7
9
|
end
|
8
10
|
|
@@ -28,13 +30,18 @@ class PDFKit
|
|
28
30
|
:margin_bottom => '0.75in',
|
29
31
|
:margin_left => '0.75in'
|
30
32
|
}
|
31
|
-
|
33
|
+
|
34
|
+
@options = options.dup
|
35
|
+
unless source.url?
|
36
|
+
@options.merge! find_options_in_meta(url_file_or_html)
|
37
|
+
end
|
38
|
+
@options = normalize_options(default_options.merge(@options))
|
32
39
|
|
33
|
-
raise NoExecutableError.new
|
40
|
+
raise NoExecutableError.new unless File.exists?(PDFKit.configuration.wkhtmltopdf)
|
34
41
|
end
|
35
42
|
|
36
43
|
def command
|
37
|
-
args = [wkhtmltopdf]
|
44
|
+
args = [PDFKit.configuration.wkhtmltopdf]
|
38
45
|
args += @options.to_a.flatten.compact
|
39
46
|
args << '--quiet'
|
40
47
|
|
@@ -45,17 +52,20 @@ class PDFKit
|
|
45
52
|
end
|
46
53
|
|
47
54
|
args << '-' # Read PDF from stdout
|
48
|
-
args
|
55
|
+
args
|
49
56
|
end
|
50
57
|
|
51
58
|
def to_pdf
|
52
59
|
append_stylesheets
|
53
60
|
|
54
|
-
pdf =
|
61
|
+
pdf = Kernel.open('|-', "w+")
|
62
|
+
exec(*command) if pdf.nil?
|
55
63
|
pdf.puts(@source.to_s) if @source.html?
|
56
64
|
pdf.close_write
|
57
65
|
result = pdf.gets(nil)
|
58
66
|
pdf.close_read
|
67
|
+
|
68
|
+
raise "command failed: #{command}" if result.to_s.strip.empty?
|
59
69
|
return result
|
60
70
|
end
|
61
71
|
|
@@ -64,9 +74,24 @@ class PDFKit
|
|
64
74
|
end
|
65
75
|
|
66
76
|
protected
|
67
|
-
|
68
|
-
def
|
69
|
-
|
77
|
+
|
78
|
+
def find_options_in_meta(body)
|
79
|
+
pdfkit_meta_tags(body).inject({}) do |found, tag|
|
80
|
+
name = tag.attributes["name"].sub(/^#{PDFKit.configuration.meta_tag_prefix}/, '').to_sym
|
81
|
+
found.merge(name => tag.attributes["content"])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def pdfkit_meta_tags(body)
|
86
|
+
require 'rexml/document'
|
87
|
+
xml_body = REXML::Document.new(body)
|
88
|
+
found = []
|
89
|
+
xml_body.elements.each("html/head/meta") do |tag|
|
90
|
+
found << tag if tag.attributes['name'].to_s =~ /^#{PDFKit.configuration.meta_tag_prefix}/
|
91
|
+
end
|
92
|
+
found
|
93
|
+
rescue # rexml random crash on invalid xml
|
94
|
+
[]
|
70
95
|
end
|
71
96
|
|
72
97
|
def style_tag_for(stylesheet)
|
@@ -87,6 +112,7 @@ class PDFKit
|
|
87
112
|
|
88
113
|
def normalize_options(options)
|
89
114
|
normalized_options = {}
|
115
|
+
|
90
116
|
options.each do |key, value|
|
91
117
|
next if !value
|
92
118
|
normalized_key = "--#{normalize_arg key}"
|
@@ -103,8 +129,6 @@ class PDFKit
|
|
103
129
|
case value
|
104
130
|
when TrueClass
|
105
131
|
nil
|
106
|
-
when String
|
107
|
-
value.match(/\s/) ? "\"#{value}\"" : value
|
108
132
|
else
|
109
133
|
value
|
110
134
|
end
|
data/pdfkit.gemspec
CHANGED
@@ -5,14 +5,15 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{pdfkit}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["jdpace"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-07-16}
|
13
|
+
s.default_executable = %q{pdfkit}
|
13
14
|
s.description = %q{Uses wkhtmltopdf to create PDFs using HTML}
|
14
15
|
s.email = %q{jared@codewordstudios.com}
|
15
|
-
s.executables = ["
|
16
|
+
s.executables = ["pdfkit"]
|
16
17
|
s.extra_rdoc_files = [
|
17
18
|
"LICENSE",
|
18
19
|
"README.md"
|
@@ -20,32 +21,40 @@ Gem::Specification.new do |s|
|
|
20
21
|
s.files = [
|
21
22
|
".document",
|
22
23
|
".gitignore",
|
24
|
+
".rspec",
|
23
25
|
"LICENSE",
|
24
26
|
"README.md",
|
25
27
|
"Rakefile",
|
26
28
|
"VERSION",
|
27
|
-
"bin/
|
28
|
-
"bin/wkhtmltopdf-osx-i386-0-9-9",
|
29
|
-
"bin/wkhtmltopdf-proxy",
|
29
|
+
"bin/pdfkit",
|
30
30
|
"lib/pdfkit.rb",
|
31
|
+
"lib/pdfkit/configuration.rb",
|
31
32
|
"lib/pdfkit/middleware.rb",
|
32
33
|
"lib/pdfkit/pdfkit.rb",
|
33
34
|
"lib/pdfkit/source.rb",
|
34
35
|
"pdfkit.gemspec",
|
35
36
|
"spec/fixtures/example.css",
|
36
37
|
"spec/fixtures/example.html",
|
38
|
+
"spec/middleware_spec.rb",
|
37
39
|
"spec/pdfkit_spec.rb",
|
38
40
|
"spec/source_spec.rb",
|
39
41
|
"spec/spec_helper.rb"
|
40
42
|
]
|
41
43
|
s.homepage = %q{http://github.com/jdpace/PDFKit}
|
44
|
+
s.post_install_message = %q{**************************************************
|
45
|
+
|
46
|
+
Run sudo pdfkit --install-wkhtmltopdf to install wkhtmltopdf binaries.
|
47
|
+
(run pdfkit --help to see more options)
|
48
|
+
|
49
|
+
**************************************************
|
50
|
+
}
|
42
51
|
s.rdoc_options = ["--charset=UTF-8"]
|
43
52
|
s.require_paths = ["lib"]
|
44
53
|
s.rubygems_version = %q{1.3.7}
|
45
54
|
s.summary = %q{HTML+CSS -> PDF}
|
46
55
|
s.test_files = [
|
47
56
|
"spec/middleware_spec.rb",
|
48
|
-
"spec/
|
57
|
+
"spec/pdfkit_spec.rb",
|
49
58
|
"spec/source_spec.rb",
|
50
59
|
"spec/spec_helper.rb"
|
51
60
|
]
|
data/spec/middleware_spec.rb
CHANGED
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe PDFKit::Middleware do
|
4
4
|
describe "#translate_paths" do
|
5
|
+
|
5
6
|
before do
|
6
7
|
@pdf = PDFKit::Middleware.new({})
|
7
8
|
@env = {'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com'}
|
@@ -18,5 +19,31 @@ describe PDFKit::Middleware do
|
|
18
19
|
body = @pdf.send :translate_paths, @body, @env
|
19
20
|
body.should == "<link href=\"http://example.com/stylesheets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
|
20
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
|
+
end
|
29
|
+
|
30
|
+
describe "#set_request_to_render_as_pdf" do
|
31
|
+
|
32
|
+
before do
|
33
|
+
@pdf = PDFKit::Middleware.new({})
|
34
|
+
|
35
|
+
@pdf_env = {'PATH_INFO' => Pathname.new("file.pdf"), 'REQUEST_URI' => Pathname.new("file.pdf")}
|
36
|
+
@non_pdf_env = {'PATH_INFO' => Pathname.new("file.txt"), 'REQUEST_URI' => Pathname.new("file.txt")}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should replace .pdf in PATH_INFO when the extname is .pdf" do
|
40
|
+
@pdf.send :set_request_to_render_as_pdf, @pdf_env
|
41
|
+
@pdf_env['PATH_INFO'].should == "file"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should replace .pdf in REQUEST_URI when the extname is .pdf" do
|
45
|
+
@pdf.send :set_request_to_render_as_pdf, @pdf_env
|
46
|
+
@pdf_env['REQUEST_URI'].should == "file"
|
47
|
+
end
|
21
48
|
end
|
22
49
|
end
|
data/spec/pdfkit_spec.rb
CHANGED
@@ -43,9 +43,9 @@ describe PDFKit do
|
|
43
43
|
context "command" do
|
44
44
|
it "should contstruct the correct command" do
|
45
45
|
pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12)
|
46
|
-
pdfkit.command.should include('wkhtmltopdf')
|
47
|
-
pdfkit.command.
|
48
|
-
pdfkit.command.
|
46
|
+
pdfkit.command[0].should include('wkhtmltopdf')
|
47
|
+
pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Letter'
|
48
|
+
pdfkit.command[pdfkit.command.index('--toc-l1-font-size') + 1].should == 12
|
49
49
|
end
|
50
50
|
|
51
51
|
it "will not include default options it is told to omit" do
|
@@ -57,23 +57,29 @@ describe PDFKit do
|
|
57
57
|
|
58
58
|
it "should encapsulate string arguments in quotes" do
|
59
59
|
pdfkit = PDFKit.new('html', :header_center => "foo [page]")
|
60
|
-
pdfkit.command.
|
60
|
+
pdfkit.command[pdfkit.command.index('--header-center') + 1].should == 'foo [page]'
|
61
61
|
end
|
62
62
|
|
63
63
|
it "read the source from stdin if it is html" do
|
64
64
|
pdfkit = PDFKit.new('html')
|
65
|
-
pdfkit.command.should
|
65
|
+
pdfkit.command[-2..-1].should == ['-', '-']
|
66
66
|
end
|
67
67
|
|
68
68
|
it "specify the URL to the source if it is a url" do
|
69
69
|
pdfkit = PDFKit.new('http://google.com')
|
70
|
-
pdfkit.command.should
|
70
|
+
pdfkit.command[-2..-1].should == ['http://google.com', '-']
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should specify the path to the source if it is a file" do
|
74
74
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
75
75
|
pdfkit = PDFKit.new(File.new(file_path))
|
76
|
-
pdfkit.command.should
|
76
|
+
pdfkit.command[-2..-1].should == [file_path, '-']
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should detect special pdfkit meta tags" do
|
80
|
+
body = %{<html><head><meta name="pdfkit-page-size" content="Letter"/></head></html>}
|
81
|
+
pdfkit = PDFKit.new(body)
|
82
|
+
pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Letter'
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
@@ -127,4 +133,21 @@ describe PDFKit do
|
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|
136
|
+
context "security" do
|
137
|
+
before do
|
138
|
+
@test_path = File.join(SPEC_ROOT,'fixtures','security-oops')
|
139
|
+
File.delete(@test_path) if File.exist?(@test_path)
|
140
|
+
end
|
141
|
+
|
142
|
+
after do
|
143
|
+
File.delete(@test_path) if File.exist?(@test_path)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should not allow shell injection in options" do
|
147
|
+
pdfkit = PDFKit.new('html', :header_center => "a title\"; touch #{@test_path} #")
|
148
|
+
pdfkit.to_pdf
|
149
|
+
File.exist?(@test_path).should be_false
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
130
153
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pdfkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- jdpace
|
@@ -15,8 +15,8 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
19
|
-
default_executable:
|
18
|
+
date: 2010-07-16 00:00:00 -04:00
|
19
|
+
default_executable: pdfkit
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: rspec
|
@@ -71,9 +71,7 @@ dependencies:
|
|
71
71
|
description: Uses wkhtmltopdf to create PDFs using HTML
|
72
72
|
email: jared@codewordstudios.com
|
73
73
|
executables:
|
74
|
-
-
|
75
|
-
- wkhtmltopdf-osx-i386-0-9-9
|
76
|
-
- wkhtmltopdf-proxy
|
74
|
+
- pdfkit
|
77
75
|
extensions: []
|
78
76
|
|
79
77
|
extra_rdoc_files:
|
@@ -82,30 +80,36 @@ extra_rdoc_files:
|
|
82
80
|
files:
|
83
81
|
- .document
|
84
82
|
- .gitignore
|
83
|
+
- .rspec
|
85
84
|
- LICENSE
|
86
85
|
- README.md
|
87
86
|
- Rakefile
|
88
87
|
- VERSION
|
89
|
-
- bin/
|
90
|
-
- bin/wkhtmltopdf-osx-i386-0-9-9
|
91
|
-
- bin/wkhtmltopdf-proxy
|
88
|
+
- bin/pdfkit
|
92
89
|
- lib/pdfkit.rb
|
90
|
+
- lib/pdfkit/configuration.rb
|
93
91
|
- lib/pdfkit/middleware.rb
|
94
92
|
- lib/pdfkit/pdfkit.rb
|
95
93
|
- lib/pdfkit/source.rb
|
96
94
|
- pdfkit.gemspec
|
97
95
|
- spec/fixtures/example.css
|
98
96
|
- spec/fixtures/example.html
|
97
|
+
- spec/middleware_spec.rb
|
99
98
|
- spec/pdfkit_spec.rb
|
100
99
|
- spec/source_spec.rb
|
101
100
|
- spec/spec_helper.rb
|
102
|
-
- spec/middleware_spec.rb
|
103
|
-
- spec/PDFKit_spec.rb
|
104
101
|
has_rdoc: true
|
105
102
|
homepage: http://github.com/jdpace/PDFKit
|
106
103
|
licenses: []
|
107
104
|
|
108
|
-
post_install_message:
|
105
|
+
post_install_message: |
|
106
|
+
**************************************************
|
107
|
+
|
108
|
+
Run sudo pdfkit --install-wkhtmltopdf to install wkhtmltopdf binaries.
|
109
|
+
(run pdfkit --help to see more options)
|
110
|
+
|
111
|
+
**************************************************
|
112
|
+
|
109
113
|
rdoc_options:
|
110
114
|
- --charset=UTF-8
|
111
115
|
require_paths:
|
@@ -137,6 +141,6 @@ specification_version: 3
|
|
137
141
|
summary: HTML+CSS -> PDF
|
138
142
|
test_files:
|
139
143
|
- spec/middleware_spec.rb
|
140
|
-
- spec/
|
144
|
+
- spec/pdfkit_spec.rb
|
141
145
|
- spec/source_spec.rb
|
142
146
|
- spec/spec_helper.rb
|
Binary file
|
Binary file
|
data/bin/wkhtmltopdf-proxy
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
executable = `which wkhtmltopdf`.chomp
|
4
|
-
|
5
|
-
if executable.empty?
|
6
|
-
|
7
|
-
binary = case RUBY_PLATFORM
|
8
|
-
when /linux/
|
9
|
-
'wkhtmltopdf-linux-i386-0-9-9'
|
10
|
-
when /darwin/
|
11
|
-
'wkhtmltopdf-osx-i386-0-9-9'
|
12
|
-
else
|
13
|
-
raise "No bundled binaries found for your system. Please install wkhtmltopdf."
|
14
|
-
end
|
15
|
-
executable = File.join(File.dirname(__FILE__), binary)
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
arguments = $*.map { |arg| arg.include?(' ') ? %Q("#{arg}") : arg }
|
20
|
-
|
21
|
-
system(executable + " " + arguments.join(" "))
|
data/spec/PDFKit_spec.rb
DELETED
@@ -1,130 +0,0 @@
|
|
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
|