ferrum_pdf 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +133 -23
- data/lib/ferrum_pdf/controller.rb +27 -0
- data/lib/ferrum_pdf/html_preprocessor.rb +26 -0
- data/lib/ferrum_pdf/railtie.rb +1 -1
- data/lib/ferrum_pdf/version.rb +1 -1
- data/lib/ferrum_pdf.rb +27 -46
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad27a3b666b15d934cc1bbf678ac52bfe86fc421723c89a60a123b3599aa2c39
|
4
|
+
data.tar.gz: 0a9bf56518d53ff03f84b9a9143280f97effe45b26edda3695a767d871bb0f73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a2fa255b8d7484952959023ac2ca320ce68259857adbba20fbb0dc9c455e40e6db6a7088daf22b8f70f85da2d31f8fc2c1550a6f6a2ad97cb9920a1841bfd2b
|
7
|
+
data.tar.gz: ed0d20754dee52a621880ef3ffc95894749b8ddfc5796226029d2417c2b6c18e4b29fb94bbae0dd3249d9f7e56e936c6b429f7640ebc7eb33bc5ba72556fb9dc
|
data/README.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# FerrumPdf
|
2
2
|
|
3
|
-
PDFs for Rails using [Ferrum](https://github.com/rubycdp/ferrum) & headless Chrome
|
3
|
+
PDFs & screentshots for Rails using [Ferrum](https://github.com/rubycdp/ferrum) & headless Chrome.
|
4
|
+
|
5
|
+
Inspired by [Grover](https://github.com/Studiosity/grover).
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
9
|
+
First, make sure Chrome is installed
|
10
|
+
|
7
11
|
Run the following or add the gem to your Gemfile:
|
8
12
|
|
9
13
|
```ruby
|
@@ -12,7 +16,16 @@ bundle add "ferrum_pdf"
|
|
12
16
|
|
13
17
|
## Usage
|
14
18
|
|
15
|
-
|
19
|
+
You can use FerrumPdf to render [PDFs](#pdfs) and [Screenshots](#screenshots)
|
20
|
+
|
21
|
+
### 📄 PDFs
|
22
|
+
|
23
|
+
There are two ways to render PDFs:
|
24
|
+
|
25
|
+
* [FerrumPdf.render_pdf](#render-pdfs)
|
26
|
+
* [render_pdf in Rails](#render-pdfs-from-rails-controllers)
|
27
|
+
|
28
|
+
#### Render PDFs from Rails controllers
|
16
29
|
|
17
30
|
Use the `render_pdf` helper in Rails controllers to render a PDF from the current action.
|
18
31
|
|
@@ -20,51 +33,148 @@ Use the `render_pdf` helper in Rails controllers to render a PDF from the curren
|
|
20
33
|
def show
|
21
34
|
respond_to do |format|
|
22
35
|
format.html
|
23
|
-
format.pdf {
|
36
|
+
format.pdf {
|
37
|
+
pdf = render_pdf()
|
38
|
+
send_data pdf, disposition: :inline, filename: "example.pdf"
|
39
|
+
}
|
24
40
|
end
|
25
41
|
end
|
26
42
|
```
|
27
43
|
|
28
|
-
You can also customize which template is rendered:
|
44
|
+
You can also customize which template is rendered. This will render the template to string with `render_to_string` in Rails, then pass it along to Chrome. For example, you can add headers and footers using `pdf_options` and use a specific layout:
|
29
45
|
|
30
46
|
```ruby
|
31
|
-
render_pdf(
|
47
|
+
render_pdf(
|
48
|
+
layout: "pdf,
|
49
|
+
pdf_options: {
|
50
|
+
display_header_footer: true,
|
51
|
+
header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE,
|
52
|
+
footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE
|
53
|
+
}
|
54
|
+
)
|
55
|
+
```
|
56
|
+
|
57
|
+
#### Render PDFs
|
58
|
+
|
59
|
+
FerrumPdf can generate a PDF from HTML or a URL:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
FerrumPdf.render_pdf(html: content)
|
63
|
+
FerrumPdf.render_pdf(url: "https://google.com")
|
64
|
+
```
|
65
|
+
|
66
|
+
You can also pass host and protocol to convert any relative paths to full URLs. This is helpful for converting relative asset paths to full URLs.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
FerrumPdf.render_pdf(
|
70
|
+
html: content, # Provide HTML
|
71
|
+
url: "https://example.com", # or provide a URL to the content
|
72
|
+
host: request.base_url + "/", # Used for setting the host for relative paths
|
73
|
+
protocol: request.protocol, # Used for handling relative protocol paths
|
74
|
+
|
75
|
+
pdf_options: {
|
76
|
+
landscape: false, # paper orientation
|
77
|
+
scale: 1, # Scale of the webpage rendering
|
78
|
+
format: nil,
|
79
|
+
paper_width: 8.5, # Paper width in inches
|
80
|
+
paper_height: 11, # Paper height in inches
|
81
|
+
page_ranges: nil, # Paper ranges to print "1-5, 8 11-13"
|
82
|
+
|
83
|
+
# Margins (in inches, defaults to 1cm)
|
84
|
+
margin_top: 0.4,
|
85
|
+
margin_bottom: 0.4,
|
86
|
+
margin_left: 0.4,
|
87
|
+
margin_right: 0.4,
|
88
|
+
|
89
|
+
# Header, footer, and background options
|
90
|
+
#
|
91
|
+
# Variables can be used with CSS classes. For example <span class="date"></span>
|
92
|
+
# * date: formatted print date
|
93
|
+
# * title: document title
|
94
|
+
# * url: document location
|
95
|
+
# * pageNumber: current page number
|
96
|
+
# *totalPages: total pages in the document
|
97
|
+
|
98
|
+
display_header_footer: false,
|
99
|
+
print_background: false, # Print background graphics
|
100
|
+
header_template: "", # HTML template for the header
|
101
|
+
footer_template: "", # HTML template for the footer
|
102
|
+
}
|
103
|
+
)
|
32
104
|
```
|
33
105
|
|
34
|
-
|
106
|
+
See [Chrome DevTools Protocol docs](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) and [Ferrum's `#pdf` docs](https://github.com/rubycdp/ferrum?tab=readme-ov-file#pdfoptions--string--boolean) for the full set of options.
|
107
|
+
|
108
|
+
### 🎆 Screenshots
|
109
|
+
|
110
|
+
There are two ways to render Screenshots:
|
111
|
+
|
112
|
+
* [FerrumPdf.render_screenshot](#render-screenshot)
|
113
|
+
* [render_screenshot in Rails](#render-screenshots-from-rails-controllers)
|
114
|
+
|
115
|
+
#### Render Screenshot from Rails controller
|
35
116
|
|
36
|
-
|
117
|
+
Use the `render_screenshot` helper in Rails controllers to render a PDF from the current action.
|
37
118
|
|
38
119
|
```ruby
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
120
|
+
def show
|
121
|
+
respond_to do |format|
|
122
|
+
format.html
|
123
|
+
format.png {
|
124
|
+
screenshot = render_screenshot()
|
125
|
+
send_data screenshot, disposition: :inline, filename: "example.png"
|
126
|
+
}
|
127
|
+
end
|
128
|
+
end
|
44
129
|
```
|
45
130
|
|
46
|
-
|
131
|
+
You can also customize which template is rendered. This will render the template to string with `render_to_string` in Rails, then pass it along to Chrome.
|
47
132
|
|
48
|
-
|
133
|
+
```ruby
|
134
|
+
render_screenshot(
|
135
|
+
screenshot_options: {
|
136
|
+
format: "png" # or "jpeg"
|
137
|
+
quality: nil # Integer 0-100 works for jpeg only
|
138
|
+
full: true # Boolean whether you need full page screenshot or a viewport
|
139
|
+
selector: nil # String css selector for given element, optional
|
140
|
+
area: nil # Hash area for screenshot, optional. {x: 0, y: 0, width: 100, height: 100}
|
141
|
+
scale: nil # Float zoom in/out
|
142
|
+
background_color: nil # Ferrum::RGBA.new(0, 0, 0, 0.0)
|
143
|
+
}
|
144
|
+
)
|
145
|
+
```
|
146
|
+
|
147
|
+
See [Ferrum screenshot docs](https://github.com/rubycdp/ferrum?tab=readme-ov-file#screenshotoptions--string--integer) for the full set of options.
|
148
|
+
|
149
|
+
#### Render Screenshots
|
150
|
+
|
151
|
+
FerrumPdf can generate a screenshot from HTML or a URL:
|
49
152
|
|
50
153
|
```ruby
|
51
|
-
FerrumPdf.
|
154
|
+
FerrumPdf.render_screenshot(html: content)
|
155
|
+
FerrumPdf.render_screenshot(url: "https://google.com")
|
52
156
|
```
|
53
157
|
|
54
158
|
You can also pass host and protocol to convert any relative paths to full URLs. This is helpful for converting relative asset paths to full URLs.
|
55
159
|
|
56
160
|
```ruby
|
57
|
-
FerrumPdf.
|
58
|
-
html:
|
59
|
-
|
60
|
-
|
61
|
-
|
161
|
+
FerrumPdf.render_screenshot(
|
162
|
+
html: "",
|
163
|
+
url: "",
|
164
|
+
root_url: "",
|
165
|
+
protocol: "",
|
166
|
+
screenshot_options: {
|
167
|
+
format: "png" # or "jpeg"
|
168
|
+
quality: nil # Integer 0-100 works for jpeg only
|
169
|
+
full: true # Boolean whether you need full page screenshot or a viewport
|
170
|
+
selector: nil # String css selector for given element, optional
|
171
|
+
area: nil # Hash area for screenshot, optional. {x: 0, y: 0, width: 100, height: 100}
|
172
|
+
scale: nil # Float zoom in/out
|
173
|
+
background_color: nil # Ferrum::RGBA.new(0, 0, 0, 0.0)
|
174
|
+
}
|
62
175
|
)
|
63
176
|
```
|
64
177
|
|
65
|
-
See Chrome DevTools Protocol docs: https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
|
66
|
-
And Ferrum's `#pdf` docs: https://github.com/rubycdp/ferrum?tab=readme-ov-file#pdfoptions--string--boolean
|
67
|
-
|
68
178
|
## Contributing
|
69
179
|
|
70
180
|
If you have an issue you'd like to submit, please do so using the issue tracker in GitHub. In order for us to help you in the best way possible, please be as detailed as you can.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FerrumPdf
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def render_pdf(pdf_options: {}, **rendering)
|
6
|
+
content = render_to_string(**rendering.with_defaults(formats: [ :html ]))
|
7
|
+
|
8
|
+
FerrumPdf.render_pdf(
|
9
|
+
html: content,
|
10
|
+
host: request.base_url + "/",
|
11
|
+
protocol: request.protocol,
|
12
|
+
pdf_options: pdf_options
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_screenshot(screenshot_options: {}, **rendering)
|
17
|
+
content = render_to_string(**rendering.with_defaults(formats: [ :html ]))
|
18
|
+
|
19
|
+
FerrumPdf.render_screenshot(
|
20
|
+
html: content,
|
21
|
+
host: request.base_url + "/",
|
22
|
+
protocol: request.protocol,
|
23
|
+
screenshot_options: screenshot_options
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FerrumPdf
|
2
|
+
# Helper module for preparing HTML for conversion
|
3
|
+
#
|
4
|
+
# Sourced from the PDFKit project
|
5
|
+
# @see https://github.com/pdfkit/pdfkit
|
6
|
+
module HTMLPreprocessor
|
7
|
+
# Change relative paths to absolute, and relative protocols to absolute protocols
|
8
|
+
def self.process(html, root_url, protocol)
|
9
|
+
html = translate_relative_paths(html, root_url) if root_url
|
10
|
+
html = translate_relative_protocols(html, protocol) if protocol
|
11
|
+
html
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.translate_relative_paths(html, root_url)
|
15
|
+
# Try out this regexp using rubular http://rubular.com/r/hiAxBNX7KE
|
16
|
+
html.gsub(%r{(href|src)=(['"])/([^/"']([^"']*|[^"']*))?['"]}, "\\1=\\2#{root_url}\\3\\2")
|
17
|
+
end
|
18
|
+
private_class_method :translate_relative_paths
|
19
|
+
|
20
|
+
def self.translate_relative_protocols(body, protocol)
|
21
|
+
# Try out this regexp using rubular http://rubular.com/r/0Ohk0wFYxV
|
22
|
+
body.gsub(%r{(href|src)=(['"])//([^"']*|[^"']*)['"]}, "\\1=\\2#{protocol}://\\3\\2")
|
23
|
+
end
|
24
|
+
private_class_method :translate_relative_protocols
|
25
|
+
end
|
26
|
+
end
|
data/lib/ferrum_pdf/railtie.rb
CHANGED
data/lib/ferrum_pdf/version.rb
CHANGED
data/lib/ferrum_pdf.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "ferrum_pdf/version"
|
2
2
|
require "ferrum_pdf/railtie"
|
3
|
-
|
4
3
|
require "ferrum"
|
5
4
|
|
6
5
|
module FerrumPdf
|
@@ -10,59 +9,41 @@ module FerrumPdf
|
|
10
9
|
<div class='text right'><span class='pageNumber'></span>/<span class='totalPages'></span></div>
|
11
10
|
HTML
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
12
|
+
autoload :Controller, "ferrum_pdf/controller"
|
13
|
+
autoload :HTMLPreprocessor, "ferrum_pdf/html_preprocessor"
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
if html
|
20
|
-
page.content = FerrumPdf::HTMLPreprocessor.process(html, host, protocol)
|
21
|
-
page.network.wait_for_idle
|
22
|
-
else
|
23
|
-
page.go_to(url)
|
24
|
-
end
|
25
|
-
page.pdf(**pdf_options.with_defaults(encoding: :binary))
|
26
|
-
end
|
27
|
-
end
|
15
|
+
mattr_accessor :include_controller_module
|
16
|
+
@@include_controller_module = true
|
28
17
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# @see https://github.com/pdfkit/pdfkit
|
33
|
-
module HTMLPreprocessor
|
34
|
-
# Change relative paths to absolute, and relative protocols to absolute protocols
|
35
|
-
def self.process(html, root_url, protocol)
|
36
|
-
html = translate_relative_paths(html, root_url) if root_url
|
37
|
-
html = translate_relative_protocols(html, protocol) if protocol
|
38
|
-
html
|
18
|
+
class << self
|
19
|
+
def browser(**options)
|
20
|
+
@browser ||= Ferrum::Browser.new(options)
|
39
21
|
end
|
40
22
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
23
|
+
def render_pdf(html: nil, url: nil, host: nil, protocol: nil, pdf_options: {})
|
24
|
+
render(host: host, protocol: protocol, html: html, url: url) do |page|
|
25
|
+
page.pdf(**pdf_options.with_defaults(encoding: :binary))
|
26
|
+
end
|
44
27
|
end
|
45
|
-
private_class_method :translate_relative_paths
|
46
28
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
29
|
+
def render_screenshot(html: nil, url: nil, host: nil, protocol: nil, screenshot_options: {})
|
30
|
+
render(host: host, protocol: protocol, html: html, url: url) do |page|
|
31
|
+
page.screenshot(**screenshot_options.with_defaults(encoding: :binary, full: true))
|
32
|
+
end
|
50
33
|
end
|
51
|
-
private_class_method :translate_relative_protocols
|
52
|
-
end
|
53
|
-
|
54
|
-
module Controller
|
55
|
-
extend ActiveSupport::Concern
|
56
34
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
35
|
+
def render(host:, protocol:, html: nil, url: nil)
|
36
|
+
browser.create_page do |page|
|
37
|
+
if html
|
38
|
+
page.content = FerrumPdf::HTMLPreprocessor.process(html, host, protocol)
|
39
|
+
page.network.wait_for_idle
|
40
|
+
else
|
41
|
+
page.go_to(url)
|
42
|
+
end
|
43
|
+
yield page
|
44
|
+
end
|
45
|
+
rescue Ferrum::DeadBrowserError
|
46
|
+
retry
|
66
47
|
end
|
67
48
|
end
|
68
49
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ferrum_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
@@ -38,7 +38,8 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.15'
|
41
|
-
description: Export PDFs from HTML in Rails using Ferrum & headless
|
41
|
+
description: Export PDFs & screenshots from HTML in Rails using Ferrum & headless
|
42
|
+
Chrome
|
42
43
|
email:
|
43
44
|
- excid3@gmail.com
|
44
45
|
executables: []
|
@@ -49,6 +50,8 @@ files:
|
|
49
50
|
- README.md
|
50
51
|
- Rakefile
|
51
52
|
- lib/ferrum_pdf.rb
|
53
|
+
- lib/ferrum_pdf/controller.rb
|
54
|
+
- lib/ferrum_pdf/html_preprocessor.rb
|
52
55
|
- lib/ferrum_pdf/railtie.rb
|
53
56
|
- lib/ferrum_pdf/version.rb
|
54
57
|
- lib/tasks/ferrum_pdf_tasks.rake
|
@@ -77,5 +80,5 @@ requirements: []
|
|
77
80
|
rubygems_version: 3.5.16
|
78
81
|
signing_key:
|
79
82
|
specification_version: 4
|
80
|
-
summary: PDFs for Rails using Ferrum & headless Chrome
|
83
|
+
summary: PDFs & screenshots for Rails using Ferrum & headless Chrome
|
81
84
|
test_files: []
|