weasyprint 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 19a104f8a29117ef8446e128c2841ae839a26404
4
+ data.tar.gz: c8fc923c8638a25014b3ca8ac5a709cc43e11c6f
5
+ SHA512:
6
+ metadata.gz: 8236b5e5807b82760dc68e6fc96ca941c72972225150fc620a1204b096bb93e04c448cad39a20f1a744a021e631e67a3e2cd1ba2edbbe16d10f8f093a928c574
7
+ data.tar.gz: 15369cb21cc557438719aafa1e88fb9fa06b36cb51399c1e447fff299819f1cce728db53ac36188a8a4b7599b584b6f00f91394deeeab477f0ee99ea53e612ef
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,24 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .bundle
23
+ spec/custom_weasyprint_path.rb
24
+ spec/test_save.pdf
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1 @@
1
+ weasyprint
@@ -0,0 +1 @@
1
+ 2.0.0-p353
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - 2.0.0
5
+
6
+ before_script:
7
+ - "sudo apt-get install python-dev python-pip python-lxml libcairo2 libpango1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info"
@@ -0,0 +1,3 @@
1
+ 2014-07-24
2
+ ==================
3
+ * Forked from PDFKit to support weasyprint
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ weasyprint (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (4.1.4)
10
+ i18n (~> 0.6, >= 0.6.9)
11
+ json (~> 1.7, >= 1.7.7)
12
+ minitest (~> 5.1)
13
+ thread_safe (~> 0.1)
14
+ tzinfo (~> 1.1)
15
+ diff-lcs (1.2.5)
16
+ i18n (0.6.11)
17
+ json (1.8.1)
18
+ metaclass (0.0.4)
19
+ minitest (5.4.0)
20
+ mocha (1.1.0)
21
+ metaclass (~> 0.0.1)
22
+ rack (1.5.2)
23
+ rack-test (0.6.2)
24
+ rack (>= 1.0)
25
+ rake (0.9.6)
26
+ rdoc (4.0.1)
27
+ json (~> 1.4)
28
+ rspec (2.14.1)
29
+ rspec-core (~> 2.14.0)
30
+ rspec-expectations (~> 2.14.0)
31
+ rspec-mocks (~> 2.14.0)
32
+ rspec-core (2.14.8)
33
+ rspec-expectations (2.14.5)
34
+ diff-lcs (>= 1.1.3, < 2.0)
35
+ rspec-mocks (2.14.6)
36
+ thread_safe (0.3.4)
37
+ tzinfo (1.2.1)
38
+ thread_safe (~> 0.1)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ activesupport (>= 3.0.8)
45
+ mocha (>= 0.9.10)
46
+ rack-test (>= 0.5.6)
47
+ rake (~> 0.9.2)
48
+ rdoc (~> 4.0.1)
49
+ rspec (~> 2.14.0)
50
+ weasyprint!
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 jdpace; Additional modifications copyright (c) 2014 Simply Business
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.
@@ -0,0 +1,9 @@
1
+ ******************************************************************
2
+
3
+ Install weasyprint:
4
+
5
+ 1. Install by hand (recomended):
6
+
7
+ http://weasyprint.org/docs/install/
8
+
9
+ ******************************************************************
@@ -0,0 +1,131 @@
1
+ # WeasyPrint
2
+
3
+ Create PDFs using plain old HTML+CSS. Uses [weasyprint](http://weasyprint.org/) on the back-end which renders HTML.
4
+
5
+ ## Install
6
+
7
+ ### WeasyPrint
8
+ ```
9
+ gem install weasyprint
10
+ ```
11
+ ### weasyprint
12
+
13
+ 1. Install by hand (recommended):
14
+
15
+ <http://weasyprint.org/docs/install/>
16
+
17
+ ## Usage
18
+ ```ruby
19
+ # WeasyPrint.new takes the HTML and any options for weasyprint
20
+ # run `weasyprint --help` for a full list of options
21
+ kit = WeasyPrint.new(html)
22
+ kit.stylesheets << '/path/to/css/file'
23
+
24
+ # Get 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
+ # WeasyPrint.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 = WeasyPrint.new('http://google.com')
33
+ kit = WeasyPrint.new(File.new('/path/to/html'))
34
+
35
+ ## Configuration
36
+ If you're on Windows or you installed weasyprint by hand to a location other than `/usr/local/bin` you will need to tell WeasyPrint where the binary is. You can configure WeasyPrint like so:
37
+ ```ruby
38
+ # config/initializers/weasyprint.rb
39
+ WeasyPrint.configure do |config|
40
+ config.weasyprint = '/path/to/weasyprint'
41
+ config.default_options = {
42
+ :resolution => '300',
43
+ }
44
+ # Use only if your external hostname is unavailable on the server.
45
+ config.base_url = "http://localhost"
46
+ end
47
+ ```
48
+ ## Middleware
49
+ WeasyPrint comes with a middleware that allows users to get a PDF view of any page on your site by appending .pdf to the URL.
50
+
51
+ ### Middleware Setup
52
+ **Non-Rails Rack apps**
53
+ ```ruby
54
+ # in config.ru
55
+ require 'weasyprint'
56
+ use WeasyPrint::Middleware
57
+ ```
58
+ **Rails apps**
59
+ ```ruby
60
+ # in application.rb(Rails3) or environment.rb(Rails2)
61
+ require 'weasyprint'
62
+ config.middleware.use WeasyPrint::Middleware
63
+ ```
64
+ **With WeasyPrint options**
65
+ ```ruby
66
+ # options will be passed to WeasyPrint.new
67
+ config.middleware.use WeasyPrint::Middleware, :resolution => '300'
68
+ ```
69
+ **With conditions to limit routes that can be generated in pdf**
70
+ ```ruby
71
+ # conditions can be regexps (either one or an array)
72
+ config.middleware.use WeasyPrint::Middleware, {}, :only => %r[^/public]
73
+ config.middleware.use WeasyPrint::Middleware, {}, :only => [%r[^/invoice], %r[^/public]]
74
+
75
+ # conditions can be strings (either one or an array)
76
+ config.middleware.use WeasyPrint::Middleware, {}, :only => '/public'
77
+ config.middleware.use WeasyPrint::Middleware, {}, :only => ['/invoice', '/public']
78
+
79
+ # conditions can be regexps (either one or an array)
80
+ config.middleware.use WeasyPrint::Middleware, {}, :except => [%r[^/prawn], %r[^/secret]]
81
+
82
+ # conditions can be strings (either one or an array)
83
+ config.middleware.use WeasyPrint::Middleware, {}, :except => ['/secret']
84
+ ```
85
+ **Saving the generated .pdf to disk**
86
+
87
+ Setting the `WeasyPrint-save-pdf` header will cause WeasyPrint to write the generated .pdf to the file indicated by the value of the header.
88
+
89
+ For example:
90
+ ```ruby
91
+ headers['WeasyPrint-save-pdf'] = 'path/to/saved.pdf'
92
+ ```
93
+
94
+ Will cause the .pdf to be saved to `path/to/saved.pdf` in addition to being sent back to the client. If the path is not writable/non-existant the write will fail silently. The `WeasyPrint-save-pdf` header is never sent back to the client.
95
+
96
+ ## Troubleshooting
97
+
98
+ * **Single thread issue:** In development environments it is common to run a
99
+ single server process. This can cause issues when rendering your pdf
100
+ requires weasyprint to hit your server again (for images, js, css).
101
+ This is because the resource requests will get blocked by the initial
102
+ request and the initial request will be waiting on the resource
103
+ requests causing a deadlock.
104
+
105
+ This is usually not an issue in a production environment. To get
106
+ around this issue you may want to run a server with multiple workers
107
+ like Passenger or try to embed your resources within your HTML to
108
+ avoid extra HTTP requests.
109
+
110
+ Example solution (rails / bundler), add unicorn to the development
111
+ group in your Gemfile `gem 'unicorn'` then run `bundle`. Next, add a
112
+ file `config/unicorn.conf` with
113
+
114
+ worker_processes 3
115
+
116
+ Then to run the app `unicorn_rails -c config/unicorn.conf` (from rails_root)
117
+
118
+ ## Note on Patches/Pull Requests
119
+
120
+ * Fork the project.
121
+ * Setup your development environment with: `gem install bundler`; `bundle install`
122
+ * Make your feature addition or bug fix.
123
+ * Add tests for it. This is important so I don't break it in a
124
+ future version unintentionally.
125
+ * Commit, do not mess with rakefile, version, or history.
126
+ (if you want to have your own version, that is fine but bump version in a commit by itself so we can ignore when we pull)
127
+ * Send a pull request. Bonus points for topic branches.
128
+
129
+ ## Copyright
130
+
131
+ Copyright (c) 2010 Jared Pace. See LICENSE for details. Additional work Copyright (c) 2014 Simply Business
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec) do |spec|
8
+ end
9
+
10
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
11
+ spec.rcov = true
12
+ end
13
+
14
+ task :default => :spec
15
+
16
+ require 'rdoc/task'
17
+ RDoc::Task.new do |rdoc|
18
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
19
+
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = "WeasyPrint #{version}"
22
+ rdoc.rdoc_files.include('README*')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
@@ -0,0 +1,4 @@
1
+ require 'weasyprint/source'
2
+ require 'weasyprint/weasyprint'
3
+ require 'weasyprint/middleware'
4
+ require 'weasyprint/configuration'
@@ -0,0 +1,47 @@
1
+ class WeasyPrint
2
+ class Configuration
3
+ attr_accessor :meta_tag_prefix, :default_options, :root_url
4
+ attr_writer :weasyprint, :verbose
5
+
6
+ def initialize
7
+ @verbose = false
8
+ @meta_tag_prefix = 'weasyprint-'
9
+ @default_options = {
10
+ encoding: 'UTF-8',
11
+ format: 'pdf'
12
+ }
13
+ end
14
+
15
+ def weasyprint
16
+ @weasyprint ||= (defined?(Bundler::GemfileError) ? `bundle exec which weasyprint` : `which weasyprint`).chomp
17
+ end
18
+
19
+ def quiet?
20
+ !@verbose
21
+ end
22
+
23
+ def verbose?
24
+ @verbose
25
+ end
26
+ end
27
+
28
+ class << self
29
+ attr_accessor :configuration
30
+ end
31
+
32
+ # Configure WeasyPrint someplace sensible,
33
+ # like config/initializers/weasyprint.rb
34
+ #
35
+ # @example
36
+ # WeasyPrint.configure do |config|
37
+ # config.weasyprint = '/usr/bin/weasyprint'
38
+ # end
39
+
40
+ def self.configuration
41
+ @configuration ||= Configuration.new
42
+ end
43
+
44
+ def self.configure
45
+ yield(configuration)
46
+ end
47
+ end
@@ -0,0 +1,102 @@
1
+ class WeasyPrint
2
+
3
+ class Middleware
4
+
5
+ def initialize(app, options = {}, conditions = {})
6
+ @app = app
7
+ @options = options
8
+ @conditions = conditions
9
+ end
10
+
11
+ def call(env)
12
+ @request = Rack::Request.new(env)
13
+ @render_pdf = false
14
+ @caching = @conditions.delete(:caching) { false }
15
+
16
+ set_request_to_render_as_pdf(env) if render_as_pdf?
17
+ status, headers, response = @app.call(env)
18
+
19
+ if rendering_pdf? && headers['Content-Type'] =~ /text\/html|application\/xhtml\+xml/
20
+ body = response.respond_to?(:body) ? response.body : response.join
21
+ body = body.join if body.is_a?(Array)
22
+ body = WeasyPrint.new(translate_paths(body, env), @options).to_pdf
23
+ response = [body]
24
+
25
+ if headers['WeasyPrint-save-pdf']
26
+ File.open(headers['WeasyPrint-save-pdf'], 'wb') { |file| file.write(body) } rescue nil
27
+ headers.delete('WeasyPrint-save-pdf')
28
+ end
29
+
30
+ unless @caching
31
+ # Do not cache PDFs
32
+ headers.delete('ETag')
33
+ headers.delete('Cache-Control')
34
+ end
35
+
36
+ headers['Content-Length'] = (body.respond_to?(:bytesize) ? body.bytesize : body.size).to_s
37
+ headers['Content-Type'] = 'application/pdf'
38
+ end
39
+
40
+ [status, headers, response]
41
+ end
42
+
43
+ private
44
+
45
+ # Change relative paths to absolute
46
+ def translate_paths(body, env)
47
+ # Host with protocol
48
+ root = WeasyPrint.configuration.root_url || "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}/"
49
+
50
+ body.gsub(/(href|src)=(['"])\/([^\/]([^\"']*|[^"']*))['"]/, '\1=\2' + root + '\3\2')
51
+ end
52
+
53
+ def rendering_pdf?
54
+ @render_pdf
55
+ end
56
+
57
+ def render_as_pdf?
58
+ request_path_is_pdf = @request.path.match(%r{\.pdf$})
59
+
60
+ if request_path_is_pdf && @conditions[:only]
61
+ rules = [@conditions[:only]].flatten
62
+ rules.any? do |pattern|
63
+ if pattern.is_a?(Regexp)
64
+ @request.path =~ pattern
65
+ else
66
+ @request.path[0, pattern.length] == pattern
67
+ end
68
+ end
69
+ elsif request_path_is_pdf && @conditions[:except]
70
+ rules = [@conditions[:except]].flatten
71
+ rules.map do |pattern|
72
+ if pattern.is_a?(Regexp)
73
+ return false if @request.path =~ pattern
74
+ else
75
+ return false if @request.path[0, pattern.length] == pattern
76
+ end
77
+ end
78
+
79
+ return true
80
+ else
81
+ request_path_is_pdf
82
+ end
83
+ end
84
+
85
+ def set_request_to_render_as_pdf(env)
86
+ @render_pdf = true
87
+
88
+ path = @request.path.sub(%r{\.pdf$}, '')
89
+ path = path.sub(@request.script_name, '')
90
+
91
+ %w[PATH_INFO REQUEST_URI].each { |e| env[e] = path }
92
+
93
+ env['HTTP_ACCEPT'] = concat(env['HTTP_ACCEPT'], Rack::Mime.mime_type('.html'))
94
+ env['Rack-Middleware-WeasyPrint'] = 'true'
95
+ end
96
+
97
+ def concat(accepts, type)
98
+ (accepts || '').split(',').unshift(type).compact.join(',')
99
+ end
100
+
101
+ end
102
+ end