ferrum_pdf 0.1.1 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ea0c6aba4254ef7d958dec7d9f51048ce82e106ab068a413c1e3b83ec470b01
4
- data.tar.gz: e34df1014f457e4ad42a41a5a29ab9a0d0ab42027cb8d8374aeacf6557a49833
3
+ metadata.gz: ad27a3b666b15d934cc1bbf678ac52bfe86fc421723c89a60a123b3599aa2c39
4
+ data.tar.gz: 0a9bf56518d53ff03f84b9a9143280f97effe45b26edda3695a767d871bb0f73
5
5
  SHA512:
6
- metadata.gz: 68e840f65f0c0821cb8dfe6f3e249e2b5b567f8d3655c1a71a59f143beb25241aedea29fe33d95b18763a32fd5eea88bec9f6a9f4b0b6181df082544cc2453c2
7
- data.tar.gz: 123f094697e37dcee391c157ca5ba379b1b9557e8a4e7c017cb7b45861936bf24e484bec74092793dd3e64e36ffaee0a98bc613f56ed9a5e4e2dfefdbf7f1ac1
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,34 +33,145 @@ 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 ])
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
+ )
32
55
  ```
33
56
 
34
- This will render the template to string, then pass it along to FerrumPdf.
35
-
36
- ### Directly with HTML
57
+ #### Render PDFs
37
58
 
38
- FerrumPdf can generate a PDF from HTML directly:
59
+ FerrumPdf can generate a PDF from HTML or a URL:
39
60
 
40
61
  ```ruby
41
62
  FerrumPdf.render_pdf(html: content)
63
+ FerrumPdf.render_pdf(url: "https://google.com")
42
64
  ```
43
65
 
44
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.
45
67
 
46
68
  ```ruby
47
69
  FerrumPdf.render_pdf(
48
- html: content,
49
- host: request.host_with_port,
50
- protocol: request.protocol
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
+ )
104
+ ```
105
+
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
116
+
117
+ Use the `render_screenshot` helper in Rails controllers to render a PDF from the current action.
118
+
119
+ ```ruby
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
129
+ ```
130
+
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.
132
+
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:
152
+
153
+ ```ruby
154
+ FerrumPdf.render_screenshot(html: content)
155
+ FerrumPdf.render_screenshot(url: "https://google.com")
156
+ ```
157
+
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.
159
+
160
+ ```ruby
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
+ }
51
175
  )
52
176
  ```
53
177
 
@@ -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.1.1"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/ferrum_pdf.rb CHANGED
@@ -1,15 +1,38 @@
1
1
  require "ferrum_pdf/version"
2
2
  require "ferrum_pdf/railtie"
3
-
4
3
  require "ferrum"
5
4
 
6
5
  module FerrumPdf
7
- def self.browser(**options)
8
- @browser ||= Ferrum::Browser.new(options)
9
- end
6
+ DEFAULT_HEADER_TEMPLATE = "<div class='date text left'></div><div class='title text center'></div>"
7
+ DEFAULT_FOOTER_TEMPLATE = <<~HTML
8
+ <div class='url text left grow'></div>
9
+ <div class='text right'><span class='pageNumber'></span>/<span class='totalPages'></span></div>
10
+ HTML
11
+
12
+ autoload :Controller, "ferrum_pdf/controller"
13
+ autoload :HTMLPreprocessor, "ferrum_pdf/html_preprocessor"
14
+
15
+ mattr_accessor :include_controller_module
16
+ @@include_controller_module = true
17
+
18
+ class << self
19
+ def browser(**options)
20
+ @browser ||= Ferrum::Browser.new(options)
21
+ end
22
+
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
27
+ end
28
+
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
33
+ end
10
34
 
11
- def self.render_pdf(host:, protocol:, html: nil, url: nil)
12
- Tempfile.create do |file|
35
+ def render(host:, protocol:, html: nil, url: nil)
13
36
  browser.create_page do |page|
14
37
  if html
15
38
  page.content = FerrumPdf::HTMLPreprocessor.process(html, host, protocol)
@@ -17,48 +40,10 @@ module FerrumPdf
17
40
  else
18
41
  page.go_to(url)
19
42
  end
20
- page.pdf(path: file.path)
21
- file.read
43
+ yield page
22
44
  end
23
- end
24
- end
25
-
26
- # Helper module for preparing HTML for conversion
27
- #
28
- # Sourced from the PDFKit project
29
- # @see https://github.com/pdfkit/pdfkit
30
- module HTMLPreprocessor
31
- # Change relative paths to absolute, and relative protocols to absolute protocols
32
- def self.process(html, root_url, protocol)
33
- html = translate_relative_paths(html, root_url) if root_url
34
- html = translate_relative_protocols(html, protocol) if protocol
35
- html
36
- end
37
-
38
- def self.translate_relative_paths(html, root_url)
39
- # Try out this regexp using rubular http://rubular.com/r/hiAxBNX7KE
40
- html.gsub(%r{(href|src)=(['"])/([^/"']([^"']*|[^"']*))?['"]}, "\\1=\\2#{root_url}\\3\\2")
41
- end
42
- private_class_method :translate_relative_paths
43
-
44
- def self.translate_relative_protocols(body, protocol)
45
- # Try out this regexp using rubular http://rubular.com/r/0Ohk0wFYxV
46
- body.gsub(%r{(href|src)=(['"])//([^"']*|[^"']*)['"]}, "\\1=\\2#{protocol}://\\3\\2")
47
- end
48
- private_class_method :translate_relative_protocols
49
- end
50
-
51
- module Controller
52
- extend ActiveSupport::Concern
53
-
54
- def render_pdf(name = action_name, formats: [ :html ])
55
- content = render_to_string(name, formats: formats)
56
-
57
- FerrumPdf.render_pdf(
58
- html: content,
59
- host: request.host_with_port,
60
- protocol: request.protocol
61
- )
45
+ rescue Ferrum::DeadBrowserError
46
+ retry
62
47
  end
63
48
  end
64
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferrum_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-20 00:00:00.000000000 Z
11
+ date: 2024-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -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
@@ -74,8 +77,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
77
  - !ruby/object:Gem::Version
75
78
  version: '0'
76
79
  requirements: []
77
- rubygems_version: 3.5.18
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: []