rails-pdf-renderer 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f2396f2a50e521eb3641ddf19198e39504fb613541e1154cf2c050a9bec30031
4
+ data.tar.gz: 344b6c385d3432bc5571334ac263df132268fff1234946823289621dcfe986f0
5
+ SHA512:
6
+ metadata.gz: 48992c0c124af8e2c681c3ff0b0fb908548c9a1bf04553559d39c5e20044bfc02eb7b53a84e97aa8133e2850eb81dc3035041dfee045c6e751a7bc5b7b7aa16f
7
+ data.tar.gz: 14db253bc2acf01a4ac8572a9a801b7f85022a993d5e4048bfdbb3a4c8b7e336b5ef7ee4f7e49930dff8b30ad4123d942591830519ae6245b1e92488369ab862
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org/).
4
+
5
+ ## [0.1.0]
6
+ ### New Features
7
+ - Initial version
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Erik Axel Nielsen
4
+ Copyright (c) 2008 Miles Z. Sterrett
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # RailsPdfRenderer
2
+
3
+ ## Installation
4
+
5
+ Install the gem and add to the application's Gemfile by executing:
6
+
7
+ $ bundle add rails-pdf-renderer
8
+
9
+ ## Usage
10
+
11
+
12
+
13
+ ## Development
14
+
15
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
16
+
17
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
18
+
19
+ ## Contributing
20
+
21
+ Bug reports and pull requests are welcome on GitHub at https://github.com/erikaxel/rails-pdf-renderer.
22
+
23
+ ## License
24
+
25
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
26
+
27
+ Initial inspiration and code was influenced by [wicked_pdf](https://github.com/mileszs/wicked_pdf/)
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
@@ -0,0 +1,106 @@
1
+ class RailsPdfRenderer
2
+ module ActionControllerHelper
3
+ def self.prepended(base)
4
+ # Protect from trying to augment modules that appear
5
+ # as the result of adding other gems.
6
+ return if base != ActionController::Base
7
+ end
8
+
9
+ def render(*args)
10
+ options = args.first
11
+ if options.is_a?(Hash) && options.key?(:pdf)
12
+ make_and_send_pdf(options.delete(:pdf), RailsPdfRenderer.configuration.default_options.merge(options))
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ def render_to_string(*args)
19
+ options = args.first
20
+ if options.is_a?(Hash) && options.key?(:pdf)
21
+ make_pdf(RailsPdfRenderer.configuration.default_options.merge(options))
22
+ else
23
+ super
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def make_pdf(options = {})
30
+ options.delete :pdf # We dont use the filename when rendering to string
31
+
32
+ render_opts = {
33
+ :template => options[:template],
34
+ :layout => options[:layout],
35
+ :formats => options[:formats],
36
+ :handlers => options[:handlers],
37
+ :assigns => options[:assigns]
38
+ }
39
+ render_opts[:inline] = options[:inline] if options[:inline]
40
+ render_opts[:locals] = options[:locals] if options[:locals]
41
+ render_opts[:file] = options[:file] if options[:file]
42
+ html_string = render_to_string(render_opts)
43
+ pdf_from_server(html_string, options)
44
+ end
45
+
46
+ def make_and_send_pdf(pdf_name, options = {})
47
+ options[:layout] ||= false
48
+ options[:template] ||= File.join(controller_path, action_name)
49
+ options[:disposition] ||= 'inline'
50
+ if options[:show_as_html]
51
+ render_opts = {
52
+ :template => options[:template],
53
+ :layout => options[:layout],
54
+ :formats => options[:formats],
55
+ :handlers => options[:handlers],
56
+ :assigns => options[:assigns],
57
+ :content_type => 'text/html'
58
+ }
59
+ render_opts[:inline] = options[:inline] if options[:inline]
60
+ render_opts[:locals] = options[:locals] if options[:locals]
61
+ render_opts[:file] = options[:file] if options[:file]
62
+ render(render_opts)
63
+ else
64
+ pdf_content = make_pdf(options)
65
+ File.open(options[:save_to_file], 'wb') { |file| file << pdf_content } if options[:save_to_file]
66
+ send_data(pdf_content, :filename => pdf_name + '.pdf', :type => 'application/pdf', :disposition => options[:disposition]) unless options[:save_only]
67
+ end
68
+ end
69
+
70
+ def pdf_from_server(html, options)
71
+ payload = pdf_server_params(html, options)
72
+
73
+ auth_key = RailsPdfRenderer.configuration.auth_key
74
+ url = RailsPdfRenderer.configuration.url
75
+ auth_key64 = Base64.strict_encode64(auth_key)
76
+
77
+ raise "auth_key is not set, you need to set it for rails-pdf-renderer to work" if auth_key.blank?
78
+
79
+ uri = URI(url)
80
+ headers = { 'Content-Type': 'application/json', "Authorization": "Bearer #{auth_key64}" }
81
+ response = Net::HTTP.post(uri, payload.to_json, headers)
82
+
83
+ if response.kind_of? Net::HTTPSuccess
84
+ response.body
85
+ else
86
+ raise RailsPdfRenderer::Error.new(response)
87
+ end
88
+ end
89
+
90
+ def pdf_server_params(html, options = {})
91
+ request_params = {}
92
+ request_params[:html] = html
93
+ request_params[:orientation] = options[:orientation] if options.key?(:orientation)
94
+ request_params[:pageSize] = options[:pageSize] if options.key?(:pageSize)
95
+ request_params[:zoom] = options[:zoom] if options.key?(:zoom)
96
+ request_params[:height] = options[:height] if options.key?(:height)
97
+ request_params[:width] = options[:width] if options.key?(:width)
98
+ request_params[:footerTemplate] = options[:footerTemplate] if options.key?(:footerTemplate)
99
+ request_params[:marginTop] = options[:margin][:top]
100
+ request_params[:marginBottom] = options[:margin][:bottom]
101
+ request_params[:marginLeft] = options[:margin][:left]
102
+ request_params[:marginRight] = options[:margin][:right]
103
+ request_params
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,230 @@
1
+ require 'net/http'
2
+ require 'delegate'
3
+ require 'stringio'
4
+ require_relative 'path_helper'
5
+
6
+ class RailsPdfRenderer
7
+ module ActionViewHelper
8
+ ASSET_URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/
9
+
10
+ class PropshaftAsset < SimpleDelegator
11
+ def content_type
12
+ super.to_s
13
+ end
14
+
15
+ def to_s
16
+ content
17
+ end
18
+
19
+ def filename
20
+ path.to_s
21
+ end
22
+ end
23
+
24
+ def pdf_asset_base64(path)
25
+ asset = find_asset(path)
26
+ raise "Could not find asset '#{path}'" if asset.nil?
27
+
28
+ base64 = Base64.encode64(asset.to_s).gsub(/\s+/, '')
29
+ "data:#{asset.content_type};base64,#{Rack::Utils.escape(base64)}"
30
+ end
31
+
32
+ # Using `image_tag` with URLs when generating PDFs (specifically large PDFs with lots of pages) can cause buffer/stack overflows.
33
+ #
34
+ def pdf_url_base64(url)
35
+ response = Net::HTTP.get_response(URI(url))
36
+
37
+ if response.is_a?(Net::HTTPSuccess)
38
+ base64 = Base64.encode64(response.body).gsub(/\s+/, '')
39
+ "data:#{response.content_type};base64,#{Rack::Utils.escape(base64)}"
40
+ else
41
+ Rails.logger.warn("[pdf] #{response.code} #{response.message}: #{url}")
42
+ nil
43
+ end
44
+ end
45
+
46
+ def pdf_stylesheet_link_tag(*sources)
47
+ stylesheet_contents = sources.collect do |source|
48
+ source = PathHelper.add_extension(source, 'css')
49
+ "<style type='text/css'>#{read_asset(source)}</style>"
50
+ end.join("\n")
51
+
52
+ stylesheet_contents.gsub(ASSET_URL_REGEX) do
53
+ if Regexp.last_match[1].starts_with?('data:')
54
+ "url(#{Regexp.last_match[1]})"
55
+ else
56
+ "url(#{pdf_asset_path(Regexp.last_match[1])})"
57
+ end
58
+ end.html_safe
59
+ end
60
+
61
+ def pdf_stylesheet_pack_tag(*sources)
62
+ return unless defined?(Webpacker)
63
+
64
+ if running_in_development?
65
+ stylesheet_pack_tag(*sources)
66
+ else
67
+ css_text = sources.collect do |source|
68
+ source = PathHelper.add_extension(source, 'css')
69
+ pdf_stylesheet_link_tag(webpacker_source_url(source))
70
+ end.join("\n")
71
+ css_text.respond_to?(:html_safe) ? css_text.html_safe : css_text
72
+ end
73
+ end
74
+
75
+ def pdf_javascript_pack_tag(*sources)
76
+ return unless defined?(Webpacker)
77
+
78
+ if running_in_development?
79
+ javascript_pack_tag(*sources)
80
+ else
81
+ sources.collect do |source|
82
+ source = PathHelper.add_extension(source, 'js')
83
+ "<script type='text/javascript'>#{read_asset(webpacker_source_url(source))}</script>"
84
+ end.join("\n").html_safe
85
+ end
86
+ end
87
+
88
+ def pdf_image_tag(img, options = {})
89
+ image_tag pdf_asset_path(img), options
90
+ end
91
+
92
+ def pdf_javascript_src_tag(jsfile, options = {})
93
+ jsfile = PathHelper.add_extension(jsfile, 'js')
94
+ javascript_include_tag pdf_asset_path(jsfile), options
95
+ end
96
+
97
+ def pdf_javascript_include_tag(*sources)
98
+ sources.collect do |source|
99
+ source = PathHelper.add_extension(source, 'js')
100
+ "<script type='text/javascript'>#{read_asset(source)}</script>"
101
+ end.join("\n").html_safe
102
+ end
103
+
104
+ def pdf_asset_path(asset)
105
+ if (pathname = asset_pathname(asset).to_s) =~ URI_REGEXP
106
+ pathname
107
+ else
108
+ "file:///#{pathname}"
109
+ end
110
+ end
111
+
112
+ def pdf_asset_pack_path(asset)
113
+ return unless defined?(Webpacker)
114
+
115
+ if running_in_development?
116
+ asset_pack_path(asset)
117
+ else
118
+ pdf_asset_path webpacker_source_url(asset)
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ # borrowed from actionpack/lib/action_view/helpers/asset_url_helper.rb
125
+ URI_REGEXP = %r{^[-a-z]+://|^(?:cid|data):|^//}
126
+
127
+ def asset_pathname(source)
128
+ if precompiled_or_absolute_asset?(source)
129
+ asset = asset_path(source)
130
+ pathname = prepend_protocol(asset)
131
+ if pathname =~ URI_REGEXP
132
+ # asset_path returns an absolute URL using asset_host if asset_host is set
133
+ pathname
134
+ else
135
+ File.join(Rails.public_path, asset.sub(/\A#{Rails.application.config.action_controller.relative_url_root}/, ''))
136
+ end
137
+ else
138
+ asset = find_asset(source)
139
+ if asset
140
+ # older versions need pathname, Sprockets 4 supports only filename
141
+ asset.respond_to?(:filename) ? asset.filename : asset.pathname
142
+ else
143
+ File.join(Rails.public_path, source)
144
+ end
145
+ end
146
+ end
147
+
148
+ def find_asset(path)
149
+ if Rails.application.assets.respond_to?(:find_asset)
150
+ Rails.application.assets.find_asset(path, :base_path => Rails.application.root.to_s)
151
+ elsif defined?(Propshaft::Assembly) && Rails.application.assets.is_a?(Propshaft::Assembly)
152
+ asset = Rails.application.assets.load_path.find(path)
153
+ raise "Could not find asset: #{path}" if asset.nil?
154
+ PropshaftAsset.new(asset)
155
+ else
156
+ Sprockets::Railtie.build_environment(Rails.application).find_asset(path, :base_path => Rails.application.root.to_s)
157
+ end
158
+ end
159
+
160
+ # will prepend a http or default_protocol to a protocol relative URL
161
+ # or when no protcol is set.
162
+ def prepend_protocol(source)
163
+ protocol = RailsPdfRenderer.configuration.default_protocol
164
+ if source[0, 2] == '//'
165
+ source = [protocol, ':', source].join
166
+ elsif source[0] != '/' && !source[0, 8].include?('://')
167
+ source = [protocol, '://', source].join
168
+ end
169
+ source
170
+ end
171
+
172
+ def precompiled_or_absolute_asset?(source)
173
+ !Rails.configuration.respond_to?(:assets) ||
174
+ Rails.configuration.assets.compile == false ||
175
+ source.to_s[0] == '/' ||
176
+ source.to_s.match(/\Ahttps?\:\/\//)
177
+ end
178
+
179
+ def read_asset(source)
180
+ if precompiled_or_absolute_asset?(source)
181
+ pathname = asset_pathname(source)
182
+ if pathname =~ URI_REGEXP
183
+ read_from_uri(pathname)
184
+ elsif File.file?(pathname)
185
+ IO.read(pathname)
186
+ end
187
+ else
188
+ find_asset(source).to_s
189
+ end
190
+ end
191
+
192
+ def read_from_uri(uri)
193
+ asset = Net::HTTP.get(URI(uri))
194
+ asset.force_encoding('UTF-8') if asset
195
+ asset
196
+ end
197
+
198
+ def webpacker_source_url(source)
199
+ return unless webpacker_version
200
+
201
+ # In Webpacker 3.2.0 asset_pack_url is introduced
202
+ if webpacker_version >= '3.2.0'
203
+ if (host = Rails.application.config.asset_host)
204
+ asset_pack_path(source, :host => host)
205
+ else
206
+ asset_pack_url(source)
207
+ end
208
+ else
209
+ source_path = asset_pack_path(source)
210
+ # Remove last slash from root path
211
+ root_url[0...-1] + source_path
212
+ end
213
+ end
214
+
215
+ def running_in_development?
216
+ return unless webpacker_version
217
+
218
+ # :dev_server method was added in webpacker 3.0.0
219
+ if Webpacker.respond_to?(:dev_server)
220
+ Webpacker.dev_server.running?
221
+ else
222
+ Rails.env.development? || Rails.env.test?
223
+ end
224
+ end
225
+
226
+ def webpacker_version
227
+ Webpacker::VERSION
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,21 @@
1
+ class RailsPdfRenderer
2
+ class Config
3
+ include ActiveSupport::Configurable
4
+
5
+ config_accessor :auth_key
6
+ config_accessor(:url) { "https://europe-west1-lucalabs-development.cloudfunctions.net/htmlToPdf" }
7
+ config_accessor(:basic_auth) { false }
8
+ config_accessor(:default_protocol) { "https" }
9
+
10
+
11
+ config_accessor(:default_options) do {
12
+ margin: {
13
+ top: "0mm",
14
+ bottom: "0mm",
15
+ left: "0mm",
16
+ right: "0mm"
17
+ }
18
+ }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ class RailsPdfRenderer
2
+ class Error < StandardError
3
+ attr_accessor :http_response
4
+
5
+ def initialize(http_response)
6
+ @http_response = http_response
7
+ end
8
+
9
+ def message
10
+ "Got error when trying to fetch PDF from server. HTTP error #{@http_response.code} #{@http_response.message}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ class RailsPdfRenderer
2
+ module PathHelper
3
+ def self.root_path
4
+ String === Rails.root ? Pathname.new(Rails.root) : Rails.root
5
+ end
6
+
7
+ def self.add_extension(filename, extension)
8
+ filename.to_s.split('.').include?(extension) ? filename : "#{filename}.#{extension}"
9
+ end
10
+
11
+ def wicked_pdf_stylesheet_link_tag(*sources)
12
+ css_dir = PathHelper.root_path.join('public', 'stylesheets')
13
+ css_text = sources.collect do |source|
14
+ source = PathHelper.add_extension(source, 'css')
15
+ "<style type='text/css'>#{File.read(css_dir.join(source))}</style>"
16
+ end.join("\n")
17
+ css_text.respond_to?(:html_safe) ? css_text.html_safe : css_text
18
+ end
19
+
20
+ def wicked_pdf_image_tag(img, options = {})
21
+ image_tag "file:///#{PathHelper.root_path.join('public', 'images', img)}", options
22
+ end
23
+
24
+ def wicked_pdf_javascript_src_tag(jsfile, options = {})
25
+ jsfile = PathHelper.add_extension(jsfile, 'js')
26
+ type = ::Mime.respond_to?(:[]) ? ::Mime[:js] : ::Mime::JS # ::Mime[:js] cannot be used in Rails 2.3.
27
+ src = "file:///#{PathHelper.root_path.join('public', 'javascripts', jsfile)}"
28
+ content_tag('script', '', { 'type' => type, 'src' => path_to_javascript(src) }.merge(options))
29
+ end
30
+
31
+ def wicked_pdf_javascript_include_tag(*sources)
32
+ js_text = sources.collect { |source| wicked_pdf_javascript_src_tag(source, {}) }.join("\n")
33
+ js_text.respond_to?(:html_safe) ? js_text.html_safe : js_text
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'action_controller_helper'
2
+ require_relative 'action_view_helper'
3
+
4
+ class RailsPdfRenderer
5
+ if defined?(Rails.env)
6
+ class RailsPdfRendererRailtie < Rails::Railtie
7
+ initializer 'rails-pdf-renderer.register' do |_app|
8
+ ActiveSupport.on_load(:action_controller) { ActionController::Base.send :prepend, RailsPdfRenderer::ActionControllerHelper }
9
+ ActiveSupport.on_load(:action_view) { include RailsPdfRenderer::ActionViewHelper }
10
+ end
11
+ end
12
+
13
+ Mime::Type.register('application/pdf', :pdf) if Mime::Type.lookup_by_extension(:pdf).nil?
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RailsPdfRenderer
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "renderer/version"
4
+ require_relative "renderer/config"
5
+ require_relative "renderer/error"
6
+ require_relative "renderer/railtie"
7
+
8
+ class RailsPdfRenderer
9
+ def self.configuration
10
+ @configuration ||= Config.new
11
+ end
12
+
13
+ def self.configure
14
+ yield configuration
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-pdf-renderer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Erik Axel Nielsen
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-10-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: standard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Helper library to generate PDFs from Rails.
84
+ email:
85
+ - erikaxel.nielsen@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".rspec"
91
+ - CHANGELOG.md
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/rails/pdf/renderer.rb
96
+ - lib/rails/pdf/renderer/action_controller_helper.rb
97
+ - lib/rails/pdf/renderer/action_view_helper.rb
98
+ - lib/rails/pdf/renderer/config.rb
99
+ - lib/rails/pdf/renderer/error.rb
100
+ - lib/rails/pdf/renderer/path_helper.rb
101
+ - lib/rails/pdf/renderer/railtie.rb
102
+ - lib/rails/pdf/renderer/version.rb
103
+ homepage: https://github.com/erikaxel/
104
+ licenses:
105
+ - MIT
106
+ metadata:
107
+ homepage_uri: https://github.com/erikaxel/
108
+ source_code_uri: https://github.com/erikaxel/
109
+ changelog_uri: https://github.com/erikaxel/CHANGELOG.md
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 2.6.0
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubygems_version: 3.4.10
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Create PDFs directly from Rails.
129
+ test_files: []