thelinuxlich-pdfkit 0.4.6
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 +22 -0
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +35 -0
- data/LICENSE +20 -0
- data/POST_INSTALL +8 -0
- data/README.md +90 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/bin/pdfkit +72 -0
- data/lib/pdfkit.rb +5 -0
- data/lib/pdfkit/configuration.rb +41 -0
- data/lib/pdfkit/middleware.rb +61 -0
- data/lib/pdfkit/pdfkit.rb +144 -0
- data/lib/pdfkit/source.rb +27 -0
- data/pdfkit.gemspec +85 -0
- data/spec/fixtures/example.css +1 -0
- data/spec/fixtures/example.html +5 -0
- data/spec/middleware_spec.rb +49 -0
- data/spec/pdfkit_spec.rb +178 -0
- data/spec/source_spec.rb +73 -0
- data/spec/spec_helper.rb +18 -0
- metadata +138 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
gemcutter (0.6.1)
|
6
|
+
git (1.2.5)
|
7
|
+
jeweler (1.4.0)
|
8
|
+
gemcutter (>= 0.1.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rubyforge (>= 2.0.0)
|
11
|
+
json_pure (1.4.3)
|
12
|
+
mocha (0.9.8)
|
13
|
+
rake
|
14
|
+
rack (1.2.1)
|
15
|
+
rake (0.8.7)
|
16
|
+
rspec (2.0.0.beta.19)
|
17
|
+
rspec-core (= 2.0.0.beta.19)
|
18
|
+
rspec-expectations (= 2.0.0.beta.19)
|
19
|
+
rspec-mocks (= 2.0.0.beta.19)
|
20
|
+
rspec-core (2.0.0.beta.19)
|
21
|
+
rspec-expectations (2.0.0.beta.19)
|
22
|
+
diff-lcs (>= 1.1.2)
|
23
|
+
rspec-mocks (2.0.0.beta.19)
|
24
|
+
rubyforge (2.0.4)
|
25
|
+
json_pure (>= 1.1.7)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
jeweler
|
32
|
+
mocha
|
33
|
+
rack
|
34
|
+
rspec (~> 2.0.0.beta.8)
|
35
|
+
rspec-core (~> 2.0.0.beta.8)
|
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/POST_INSTALL
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
******************************************************************
|
2
|
+
|
3
|
+
Now install wkhtmltopdf binaries:
|
4
|
+
Global: sudo `which pdfkit` --install-wkhtmltopdf
|
5
|
+
or inside RVM folder: export TO=`which pdfkit | sed 's:/pdfkit:/wkhtmltopdf:'` && pdfkit --install-wkhtmltopdf
|
6
|
+
(run pdfkit --help to see more options)
|
7
|
+
|
8
|
+
******************************************************************
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
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
|
+
## Install
|
6
|
+
|
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
|
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
|
+
# 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
|
+
config.default_options = {
|
46
|
+
:page_size => 'Legal',
|
47
|
+
:print_media_type => true
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
## Middleware
|
52
|
+
|
53
|
+
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.
|
54
|
+
|
55
|
+
### Middleware Setup
|
56
|
+
|
57
|
+
**Non-Rails Rack apps**
|
58
|
+
|
59
|
+
# in config.ru
|
60
|
+
require 'pdfkit'
|
61
|
+
use PDFKit::Middleware
|
62
|
+
|
63
|
+
**Rails apps**
|
64
|
+
|
65
|
+
# in application.rb(Rails3) or environment.rb(Rails2)
|
66
|
+
require 'pdfkit'
|
67
|
+
config.middleware.use PDFKit::Middleware
|
68
|
+
|
69
|
+
**With PDFKit options**
|
70
|
+
|
71
|
+
# options will be passed to PDFKit.new
|
72
|
+
config.middleware.use PDFKit::Middleware, :print_media_type => true
|
73
|
+
|
74
|
+
## TODO
|
75
|
+
- add amd64 support in --install-wkhtmltopdf
|
76
|
+
|
77
|
+
## Note on Patches/Pull Requests
|
78
|
+
|
79
|
+
* Fork the project.
|
80
|
+
* Setup your development environment with: gem install bundler; bundle install
|
81
|
+
* Make your feature addition or bug fix.
|
82
|
+
* Add tests for it. This is important so I don't break it in a
|
83
|
+
future version unintentionally.
|
84
|
+
* Commit, do not mess with rakefile, version, or history.
|
85
|
+
(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)
|
86
|
+
* Send me a pull request. Bonus points for topic branches.
|
87
|
+
|
88
|
+
## Copyright
|
89
|
+
|
90
|
+
Copyright (c) 2010 Jared Pace. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.require(:development)
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "thelinuxlich-pdfkit"
|
10
|
+
gem.summary = %Q{HTML+CSS -> PDF}
|
11
|
+
gem.description = %Q{Uses wkhtmltopdf to create PDFs using HTML(Windows-compatible)}
|
12
|
+
gem.email = "thelinuxlich@gmail.com"
|
13
|
+
gem.homepage = "http://github.com/thelinuxlich/PDFKit"
|
14
|
+
gem.authors = ["jdpace","thelinuxlich"]
|
15
|
+
gem.add_development_dependency "rspec"
|
16
|
+
gem.add_development_dependency "rspec-core"
|
17
|
+
gem.add_development_dependency 'mocha'
|
18
|
+
gem.post_install_message = File.read('POST_INSTALL')
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rspec/core/rake_task'
|
26
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
30
|
+
spec.rcov = true
|
31
|
+
end
|
32
|
+
|
33
|
+
task :spec => :check_dependencies
|
34
|
+
|
35
|
+
task :default => :spec
|
36
|
+
|
37
|
+
require 'rake/rdoctask'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "PDFKit #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.6
|
data/bin/pdfkit
ADDED
@@ -0,0 +1,72 @@
|
|
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
|
+
elsif download =~ /.tar.lzma$/
|
43
|
+
raise "couldn't extract archive: lzcat not found" unless system("which lzcat > /dev/null 2>/dev/null")
|
44
|
+
`lzcat #{download} | tar x`
|
45
|
+
`mv wkhtmltopdf-#{arch} #{install_to}`
|
46
|
+
else
|
47
|
+
`mv #{download} #{install_to}`
|
48
|
+
end
|
49
|
+
`sudo chmod +x #{install_to}`
|
50
|
+
end
|
51
|
+
|
52
|
+
OptionParser.new do |parser|
|
53
|
+
parser.banner = "PDFKit\n\nOptions are:"
|
54
|
+
|
55
|
+
parser.on("--install-wkhtmltopdf", "Install wkhtmltopdf binaries (TO=/usr/local/bin ARCHITECTURE=i386)") do
|
56
|
+
architecture = ENV['ARCHITECTURE'] || detect_architecture
|
57
|
+
install_to = ENV['TO'] || PDFKit.configuration.wkhtmltopdf
|
58
|
+
|
59
|
+
Dir.chdir '/tmp'
|
60
|
+
|
61
|
+
cleanup(install_to)
|
62
|
+
download = download_wkhtmltopdf(architecture)
|
63
|
+
install(download, architecture, install_to)
|
64
|
+
end
|
65
|
+
|
66
|
+
parser.on("--version", "Show Version.") do
|
67
|
+
root = File.dirname(File.dirname(__FILE__))
|
68
|
+
puts File.read(File.join(root, 'VERSION'))
|
69
|
+
end
|
70
|
+
|
71
|
+
parser.on("-h", "--help", "Show this.") { puts parser; exit }
|
72
|
+
end.parse!
|
data/lib/pdfkit.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
class PDFKit
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :meta_tag_prefix, :wkhtmltopdf, :default_options
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@meta_tag_prefix = 'pdfkit-'
|
7
|
+
@wkhtmltopdf = '/usr/local/bin/wkhtmltopdf'
|
8
|
+
@default_options = {
|
9
|
+
:disable_smart_shrinking => true,
|
10
|
+
:page_size => 'Letter',
|
11
|
+
:margin_top => '0.75in',
|
12
|
+
:margin_right => '0.75in',
|
13
|
+
:margin_bottom => '0.75in',
|
14
|
+
:margin_left => '0.75in',
|
15
|
+
:encoding => "UTF-8"
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
attr_accessor :configuration
|
22
|
+
end
|
23
|
+
|
24
|
+
# Configure PDFKit someplace sensible,
|
25
|
+
# like config/initializers/pdfkit.rb
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# PDFKit.configure do |config|
|
29
|
+
# config.wkhtmltopdf = '/usr/bin/wkhtmltopdf'
|
30
|
+
# end
|
31
|
+
|
32
|
+
def self.configuration
|
33
|
+
@configuration ||= Configuration.new
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def self.configure
|
38
|
+
self.configuration
|
39
|
+
yield(configuration)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,61 @@
|
|
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
|
+
headers.delete('ETag')
|
27
|
+
headers.delete('Cache-Control')
|
28
|
+
|
29
|
+
headers["Content-Length"] = (body.respond_to?(:bytesize) ? body.bytesize : body.size).to_s
|
30
|
+
headers["Content-Type"] = "application/pdf"
|
31
|
+
|
32
|
+
response = [body]
|
33
|
+
end
|
34
|
+
|
35
|
+
[status, headers, response]
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Change relative paths to absolute
|
41
|
+
def translate_paths(body, env)
|
42
|
+
# Host with protocol
|
43
|
+
root = env['rack.url_scheme'] + "://" + env['HTTP_HOST'] + "/"
|
44
|
+
|
45
|
+
body.gsub(/(href|src)=(['"])\/([^\"']*|[^"']*)['"]/,'\1=\2'+root+'\3\2')
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_request_to_render_as_pdf(env)
|
49
|
+
@render_pdf = true
|
50
|
+
|
51
|
+
path = Pathname(env['PATH_INFO'])
|
52
|
+
['PATH_INFO','REQUEST_URI'].each { |e| env[e] = path.to_s.sub(/#{path.extname}$/,'') } if path.extname == '.pdf'
|
53
|
+
env['HTTP_ACCEPT'] = concat(env['HTTP_ACCEPT'], Rack::Mime.mime_type('.html'))
|
54
|
+
end
|
55
|
+
|
56
|
+
def concat(accepts, type)
|
57
|
+
(accepts || '').split(',').unshift(type).compact.join(',')
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
class PDFKit
|
2
|
+
|
3
|
+
class NoExecutableError < StandardError
|
4
|
+
def initialize
|
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)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ImproperSourceError < StandardError
|
12
|
+
def initialize(msg)
|
13
|
+
super("Improper Source: #{msg}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :source, :stylesheets,:fix_fonts_for_windows
|
18
|
+
attr_reader :options
|
19
|
+
|
20
|
+
def initialize(url_file_or_html, options = {})
|
21
|
+
@source = Source.new(url_file_or_html)
|
22
|
+
|
23
|
+
@stylesheets = []
|
24
|
+
@fix_fonts_for_windows = false
|
25
|
+
|
26
|
+
@options = PDFKit.configuration.default_options.merge(options)
|
27
|
+
@options.merge! find_options_in_meta(url_file_or_html) unless source.url?
|
28
|
+
@options = normalize_options(@options)
|
29
|
+
|
30
|
+
raise NoExecutableError.new unless File.exists?(PDFKit.configuration.wkhtmltopdf)
|
31
|
+
end
|
32
|
+
|
33
|
+
def command
|
34
|
+
args = [executable]
|
35
|
+
args += @options.to_a.flatten.compact
|
36
|
+
args << '--quiet'
|
37
|
+
|
38
|
+
if @source.html?
|
39
|
+
args << '-' # Get HTML from stdin
|
40
|
+
else
|
41
|
+
args << @source.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
args << '-' # Read PDF from stdout
|
45
|
+
args
|
46
|
+
end
|
47
|
+
|
48
|
+
def executable
|
49
|
+
default = PDFKit.configuration.wkhtmltopdf
|
50
|
+
return default if default !~ /^\// # its not a path, so nothing we can do
|
51
|
+
if File.exist?(default)
|
52
|
+
default
|
53
|
+
else
|
54
|
+
default.split('/').last
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_pdf(path=nil)
|
59
|
+
append_stylesheets
|
60
|
+
fix_all_font_styles_for_windows if @fix_fonts_for_windows == true
|
61
|
+
args = command
|
62
|
+
args[-1] = path if path && args[-1] == "-"
|
63
|
+
invoke = args.map {|arg| %{"#{arg.gsub('"','\\"')}"}} * " "
|
64
|
+
|
65
|
+
result = IO.popen(invoke, "w+") do |pdf|
|
66
|
+
pdf.puts(@source.to_s) if @source.html?
|
67
|
+
pdf.close_write
|
68
|
+
pdf.gets(nil)
|
69
|
+
end
|
70
|
+
result = File.open(path, "rb") {|file| file.read} if path
|
71
|
+
|
72
|
+
raise "command failed: #{invoke}" if result.to_s.strip.empty?
|
73
|
+
return result
|
74
|
+
end
|
75
|
+
|
76
|
+
alias to_file to_pdf
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
def find_options_in_meta(body)
|
81
|
+
pdfkit_meta_tags(body).inject({}) do |found, tag|
|
82
|
+
name = tag.attributes["name"].sub(/^#{PDFKit.configuration.meta_tag_prefix}/, '').to_sym
|
83
|
+
found.merge(name => tag.attributes["content"])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def pdfkit_meta_tags(body)
|
88
|
+
require 'rexml/document'
|
89
|
+
xml_body = REXML::Document.new(body)
|
90
|
+
found = []
|
91
|
+
xml_body.elements.each("html/head/meta") do |tag|
|
92
|
+
found << tag if tag.attributes['name'].to_s =~ /^#{PDFKit.configuration.meta_tag_prefix}/
|
93
|
+
end
|
94
|
+
found
|
95
|
+
rescue # rexml random crash on invalid xml
|
96
|
+
[]
|
97
|
+
end
|
98
|
+
|
99
|
+
def style_tag_for(stylesheet)
|
100
|
+
"<style>#{File.read(stylesheet)}</style>"
|
101
|
+
end
|
102
|
+
|
103
|
+
def append_stylesheets
|
104
|
+
raise ImproperSourceError.new('Stylesheets may only be added to an HTML source') if stylesheets.any? && !@source.html?
|
105
|
+
|
106
|
+
stylesheets.each do |stylesheet|
|
107
|
+
if @source.to_s.match(/<\/head>/)
|
108
|
+
@source.to_s.gsub!(/(<\/head>)/, style_tag_for(stylesheet)+'\1')
|
109
|
+
else
|
110
|
+
@source.to_s.insert(0, style_tag_for(stylesheet))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def normalize_options(options)
|
116
|
+
normalized_options = {}
|
117
|
+
|
118
|
+
options.each do |key, value|
|
119
|
+
next if !value
|
120
|
+
normalized_key = "--#{normalize_arg key}"
|
121
|
+
normalized_options[normalized_key] = normalize_value(value)
|
122
|
+
end
|
123
|
+
normalized_options
|
124
|
+
end
|
125
|
+
|
126
|
+
def normalize_arg(arg)
|
127
|
+
arg.to_s.downcase.gsub(/[^a-z0-9]/,'-')
|
128
|
+
end
|
129
|
+
|
130
|
+
def normalize_value(value)
|
131
|
+
case value
|
132
|
+
when TrueClass
|
133
|
+
nil
|
134
|
+
else
|
135
|
+
value.to_s
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def fix_all_font_styles_for_windows
|
140
|
+
@source.to_s.gsub!(/(font-family:[\s]?)([a-zA-Z,\s]+)[;]?["]?$/) do |s|
|
141
|
+
s = $1+$2.split(',').map{|font| font = "'#{font}'"}.join(',')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
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
|
data/pdfkit.gemspec
ADDED
@@ -0,0 +1,85 @@
|
|
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}
|
8
|
+
s.version = "0.4.6"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["jdpace"]
|
12
|
+
s.date = %q{2010-09-03}
|
13
|
+
s.default_executable = %q{pdfkit}
|
14
|
+
s.description = %q{Uses wkhtmltopdf to create PDFs using HTML}
|
15
|
+
s.email = %q{jared@codewordstudios.com}
|
16
|
+
s.executables = ["pdfkit"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
".rspec",
|
25
|
+
"Gemfile",
|
26
|
+
"Gemfile.lock",
|
27
|
+
"LICENSE",
|
28
|
+
"POST_INSTALL",
|
29
|
+
"README.md",
|
30
|
+
"Rakefile",
|
31
|
+
"VERSION",
|
32
|
+
"bin/pdfkit",
|
33
|
+
"lib/pdfkit.rb",
|
34
|
+
"lib/pdfkit/configuration.rb",
|
35
|
+
"lib/pdfkit/middleware.rb",
|
36
|
+
"lib/pdfkit/pdfkit.rb",
|
37
|
+
"lib/pdfkit/source.rb",
|
38
|
+
"pdfkit.gemspec",
|
39
|
+
"spec/fixtures/example.css",
|
40
|
+
"spec/fixtures/example.html",
|
41
|
+
"spec/middleware_spec.rb",
|
42
|
+
"spec/pdfkit_spec.rb",
|
43
|
+
"spec/source_spec.rb",
|
44
|
+
"spec/spec_helper.rb"
|
45
|
+
]
|
46
|
+
s.homepage = %q{http://github.com/jdpace/PDFKit}
|
47
|
+
s.post_install_message = %q{******************************************************************
|
48
|
+
|
49
|
+
Now install wkhtmltopdf binaries:
|
50
|
+
Global: sudo `which pdfkit` --install-wkhtmltopdf
|
51
|
+
or inside RVM folder: export TO=`which pdfkit | sed 's:/pdfkit:/wkhtmltopdf:'` && pdfkit --install-wkhtmltopdf
|
52
|
+
(run pdfkit --help to see more options)
|
53
|
+
|
54
|
+
******************************************************************}
|
55
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
56
|
+
s.require_paths = ["lib"]
|
57
|
+
s.rubygems_version = %q{1.3.7}
|
58
|
+
s.summary = %q{HTML+CSS -> PDF}
|
59
|
+
s.test_files = [
|
60
|
+
"spec/middleware_spec.rb",
|
61
|
+
"spec/pdfkit_spec.rb",
|
62
|
+
"spec/source_spec.rb",
|
63
|
+
"spec/spec_helper.rb"
|
64
|
+
]
|
65
|
+
|
66
|
+
if s.respond_to? :specification_version then
|
67
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
68
|
+
s.specification_version = 3
|
69
|
+
|
70
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
71
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
|
72
|
+
s.add_development_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
|
73
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
74
|
+
else
|
75
|
+
s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
|
76
|
+
s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
|
77
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
78
|
+
end
|
79
|
+
else
|
80
|
+
s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
|
81
|
+
s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
|
82
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
body { font-size: 20px; }
|
@@ -0,0 +1,49 @@
|
|
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
|
+
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
|
48
|
+
end
|
49
|
+
end
|
data/spec/pdfkit_spec.rb
ADDED
@@ -0,0 +1,178 @@
|
|
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 default to 'UTF-8' encoding" do
|
38
|
+
pdfkit = PDFKit.new('Captación')
|
39
|
+
pdfkit.options['--encoding'].should == 'UTF-8'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should not have any stylesheedt by default" do
|
43
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
44
|
+
pdfkit.stylesheets.should be_empty
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "command" do
|
49
|
+
it "should contstruct the correct command" do
|
50
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12)
|
51
|
+
pdfkit.command[0].should include('wkhtmltopdf')
|
52
|
+
pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Letter'
|
53
|
+
pdfkit.command[pdfkit.command.index('--toc-l1-font-size') + 1].should == '12'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "will not include default options it is told to omit" do
|
57
|
+
pdfkit = PDFKit.new('html')
|
58
|
+
pdfkit.command.should include('--disable-smart-shrinking')
|
59
|
+
pdfkit = PDFKit.new('html', :disable_smart_shrinking => false)
|
60
|
+
pdfkit.command.should_not include('--disable-smart-shrinking')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should encapsulate string arguments in quotes" do
|
64
|
+
pdfkit = PDFKit.new('html', :header_center => "foo [page]")
|
65
|
+
pdfkit.command[pdfkit.command.index('--header-center') + 1].should == 'foo [page]'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "read the source from stdin if it is html" do
|
69
|
+
pdfkit = PDFKit.new('html')
|
70
|
+
pdfkit.command[-2..-1].should == ['-', '-']
|
71
|
+
end
|
72
|
+
|
73
|
+
it "specify the URL to the source if it is a url" do
|
74
|
+
pdfkit = PDFKit.new('http://google.com')
|
75
|
+
pdfkit.command[-2..-1].should == ['http://google.com', '-']
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should specify the path to the source if it is a file" do
|
79
|
+
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
80
|
+
pdfkit = PDFKit.new(File.new(file_path))
|
81
|
+
pdfkit.command[-2..-1].should == [file_path, '-']
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should detect special pdfkit meta tags" do
|
85
|
+
body = %{
|
86
|
+
<html>
|
87
|
+
<head>
|
88
|
+
<meta name="pdfkit-page_size" content="Legal"/>
|
89
|
+
<meta name="pdfkit-orientation" content="Landscape"/>
|
90
|
+
</head>
|
91
|
+
</html>
|
92
|
+
}
|
93
|
+
pdfkit = PDFKit.new(body)
|
94
|
+
pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Legal'
|
95
|
+
pdfkit.command[pdfkit.command.index('--orientation') + 1].should == 'Landscape'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "#to_pdf" do
|
100
|
+
it "should generate a PDF of the HTML" do
|
101
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
102
|
+
pdf = pdfkit.to_pdf
|
103
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should generate a PDF with a numerical parameter" do
|
107
|
+
pdfkit = PDFKit.new('html', :header_spacing => 1)
|
108
|
+
pdf = pdfkit.to_pdf
|
109
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should generate a PDF with a symbol parameter" do
|
113
|
+
pdfkit = PDFKit.new('html', :page_size => :Letter)
|
114
|
+
pdf = pdfkit.to_pdf
|
115
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should have the stylesheet added to the head if it has one" do
|
119
|
+
pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
|
120
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
121
|
+
pdfkit.stylesheets << css
|
122
|
+
pdfkit.to_pdf
|
123
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style>")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should prepend style tags if the HTML doesn't have a head tag" do
|
127
|
+
pdfkit = PDFKit.new("<html><body>Hai!</body></html>")
|
128
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
129
|
+
pdfkit.stylesheets << css
|
130
|
+
pdfkit.to_pdf
|
131
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style><html>")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should throw an error if the source is not html and stylesheets have been added" do
|
135
|
+
pdfkit = PDFKit.new('http://google.com')
|
136
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
137
|
+
pdfkit.stylesheets << css
|
138
|
+
lambda { pdfkit.to_pdf }.should raise_error(PDFKit::ImproperSourceError)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "#to_file" do
|
143
|
+
before do
|
144
|
+
@file_path = File.join(SPEC_ROOT,'fixtures','test.pdf')
|
145
|
+
File.delete(@file_path) if File.exist?(@file_path)
|
146
|
+
end
|
147
|
+
|
148
|
+
after do
|
149
|
+
File.delete(@file_path)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should create a file with the PDF as content" do
|
153
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
154
|
+
pdfkit.expects(:to_pdf).returns('PDF')
|
155
|
+
file = pdfkit.to_file(@file_path)
|
156
|
+
file.should be_instance_of(File)
|
157
|
+
File.read(file.path).should == 'PDF'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "security" do
|
162
|
+
before do
|
163
|
+
@test_path = File.join(SPEC_ROOT,'fixtures','security-oops')
|
164
|
+
File.delete(@test_path) if File.exist?(@test_path)
|
165
|
+
end
|
166
|
+
|
167
|
+
after do
|
168
|
+
File.delete(@test_path) if File.exist?(@test_path)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should not allow shell injection in options" do
|
172
|
+
pdfkit = PDFKit.new('html', :header_center => "a title\"; touch #{@test_path} #")
|
173
|
+
pdfkit.to_pdf
|
174
|
+
File.exist?(@test_path).should be_false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
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,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: thelinuxlich-pdfkit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 6
|
9
|
+
version: 0.4.6
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- jdpace
|
13
|
+
- thelinuxlich
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-20 00:00:00 -02:00
|
19
|
+
default_executable: pdfkit
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
prerelease: false
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rspec-core
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *id002
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mocha
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *id003
|
60
|
+
description: Uses wkhtmltopdf to create PDFs using HTML(Windows-compatible)
|
61
|
+
email: thelinuxlich@gmail.com
|
62
|
+
executables:
|
63
|
+
- pdfkit
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files:
|
67
|
+
- LICENSE
|
68
|
+
- README.md
|
69
|
+
files:
|
70
|
+
- .document
|
71
|
+
- .gitignore
|
72
|
+
- .rspec
|
73
|
+
- Gemfile
|
74
|
+
- Gemfile.lock
|
75
|
+
- LICENSE
|
76
|
+
- POST_INSTALL
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- VERSION
|
80
|
+
- bin/pdfkit
|
81
|
+
- lib/pdfkit.rb
|
82
|
+
- lib/pdfkit/configuration.rb
|
83
|
+
- lib/pdfkit/middleware.rb
|
84
|
+
- lib/pdfkit/pdfkit.rb
|
85
|
+
- lib/pdfkit/source.rb
|
86
|
+
- pdfkit.gemspec
|
87
|
+
- spec/fixtures/example.css
|
88
|
+
- spec/fixtures/example.html
|
89
|
+
- spec/middleware_spec.rb
|
90
|
+
- spec/pdfkit_spec.rb
|
91
|
+
- spec/source_spec.rb
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
has_rdoc: true
|
94
|
+
homepage: http://github.com/thelinuxlich/PDFKit
|
95
|
+
licenses: []
|
96
|
+
|
97
|
+
post_install_message: |-
|
98
|
+
******************************************************************
|
99
|
+
|
100
|
+
Now install wkhtmltopdf binaries:
|
101
|
+
Global: sudo `which pdfkit` --install-wkhtmltopdf
|
102
|
+
or inside RVM folder: export TO=`which pdfkit | sed 's:/pdfkit:/wkhtmltopdf:'` && pdfkit --install-wkhtmltopdf
|
103
|
+
(run pdfkit --help to see more options)
|
104
|
+
|
105
|
+
******************************************************************
|
106
|
+
rdoc_options:
|
107
|
+
- --charset=UTF-8
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: 1989877863628538783
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
version: "0"
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
segments:
|
125
|
+
- 0
|
126
|
+
version: "0"
|
127
|
+
requirements: []
|
128
|
+
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 1.3.7
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: HTML+CSS -> PDF
|
134
|
+
test_files:
|
135
|
+
- spec/source_spec.rb
|
136
|
+
- spec/middleware_spec.rb
|
137
|
+
- spec/pdfkit_spec.rb
|
138
|
+
- spec/spec_helper.rb
|