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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7537d25768b2cf12df0322c63ad643c5a56dfbce85d812db0cab2f46e5f280a
4
- data.tar.gz: b36728c8686eacf59543f756ff2c3daddc20a4d9eb806580dd87faa732471cf0
3
+ metadata.gz: ad27a3b666b15d934cc1bbf678ac52bfe86fc421723c89a60a123b3599aa2c39
4
+ data.tar.gz: 0a9bf56518d53ff03f84b9a9143280f97effe45b26edda3695a767d871bb0f73
5
5
  SHA512:
6
- metadata.gz: 8f1b5d33362700a1ed42ff99068b968dc696fdb6f573b5c59f1f7be0207dc891cad8dd13994d8881fcb8a49ed774ed7aa7312445ccc15955f243dea30a8b66ce
7
- data.tar.gz: 702c650ee2f84c7eee9562cd989cb938dac2e7ca3dfe2d0e800b9315882e6309817743c639e1f8b9b47ecb2d775a1cb023a33cc68f4ef84f526aa62247358e3d
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
- ### Rails controllers
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 { send_data render_pdf, disposition: :inline, filename: "example.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(name = action_name, formats: [ :html ], pdf_options: {})
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
- This will render the template to string with `render_to_string` in Rails, then pass it along to FerrumPdf.
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
- For example, you can add headers and footers using `pdf_options`
117
+ Use the `render_screenshot` helper in Rails controllers to render a PDF from the current action.
37
118
 
38
119
  ```ruby
39
- render_pdf(pdf_options: {
40
- display_header_footer: true,
41
- header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE,
42
- footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE
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
- ### Directly with HTML
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
- FerrumPdf can generate a PDF from HTML directly:
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.render_pdf(html: content)
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.render_pdf(
58
- html: content,
59
- host: request.host_with_port,
60
- protocol: request.protocol,
61
- pdf_options: {}
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
@@ -2,7 +2,7 @@ module FerrumPdf
2
2
  class Railtie < ::Rails::Railtie
3
3
  initializer "ferrum_pdf.controller" do
4
4
  ActiveSupport.on_load(:action_controller) do
5
- include FerrumPdf::Controller
5
+ include FerrumPdf::Controller if FerrumPdf.include_controller_module
6
6
  end
7
7
  end
8
8
  end
@@ -1,3 +1,3 @@
1
1
  module FerrumPdf
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
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
- def self.browser(**options)
14
- @browser ||= Ferrum::Browser.new(options)
15
- end
12
+ autoload :Controller, "ferrum_pdf/controller"
13
+ autoload :HTMLPreprocessor, "ferrum_pdf/html_preprocessor"
16
14
 
17
- def self.render_pdf(host:, protocol:, html: nil, url: nil, pdf_options: {})
18
- browser.create_page do |page|
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
- # Helper module for preparing HTML for conversion
30
- #
31
- # Sourced from the PDFKit project
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 self.translate_relative_paths(html, root_url)
42
- # Try out this regexp using rubular http://rubular.com/r/hiAxBNX7KE
43
- html.gsub(%r{(href|src)=(['"])/([^/"']([^"']*|[^"']*))?['"]}, "\\1=\\2#{root_url}\\3\\2")
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 self.translate_relative_protocols(body, protocol)
48
- # Try out this regexp using rubular http://rubular.com/r/0Ohk0wFYxV
49
- body.gsub(%r{(href|src)=(['"])//([^"']*|[^"']*)['"]}, "\\1=\\2#{protocol}://\\3\\2")
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 render_pdf(name = action_name, formats: [ :html ], pdf_options: {})
58
- content = render_to_string(name, formats: formats)
59
-
60
- FerrumPdf.render_pdf(
61
- html: content,
62
- host: request.host_with_port,
63
- protocol: request.protocol,
64
- pdf_options: pdf_options
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.2.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 Chrome
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: []