lib/pdfkit/pdfkit.rb in pdfkit-0.3.3 vs lib/pdfkit/pdfkit.rb in pdfkit-0.4.0
- old
+ new
@@ -1,10 +1,12 @@
class PDFKit
-
+
class NoExecutableError < StandardError
def initialize
- super('Could not locate wkhtmltopdf-proxy executable')
+ msg = "No wkhtmltopdf executable found at #{PDFKit.configuration.wkhtmltopdf}\n"
+ msg << ">> Install wkhtmltopdf by hand or try running `pdfkit --install-wkhtmltopdf`"
+ super(msg)
end
end
class ImproperSourceError < StandardError
def initialize(msg)
@@ -26,50 +28,73 @@
:margin_top => '0.75in',
:margin_right => '0.75in',
:margin_bottom => '0.75in',
:margin_left => '0.75in'
}
- @options = normalize_options(default_options.merge(options))
+
+ @options = options.dup
+ unless source.url?
+ @options.merge! find_options_in_meta(url_file_or_html)
+ end
+ @options = normalize_options(default_options.merge(@options))
- raise NoExecutableError.new if wkhtmltopdf.nil? || wkhtmltopdf == ''
+ raise NoExecutableError.new unless File.exists?(PDFKit.configuration.wkhtmltopdf)
end
def command
- args = [wkhtmltopdf]
+ args = [PDFKit.configuration.wkhtmltopdf]
args += @options.to_a.flatten.compact
args << '--quiet'
if @source.html?
args << '-' # Get HTML from stdin
else
args << @source.to_s
end
args << '-' # Read PDF from stdout
- args.join(' ')
+ args
end
def to_pdf
append_stylesheets
- pdf = IO.popen(command, "w+")
+ pdf = Kernel.open('|-', "w+")
+ exec(*command) if pdf.nil?
pdf.puts(@source.to_s) if @source.html?
pdf.close_write
result = pdf.gets(nil)
pdf.close_read
+
+ raise "command failed: #{command}" if result.to_s.strip.empty?
return result
end
def to_file(path)
File.open(path,'w') {|file| file << self.to_pdf}
end
protected
-
- def wkhtmltopdf
- @wkhtmltopdf ||= `which wkhtmltopdf-proxy`.chomp
+
+ def find_options_in_meta(body)
+ pdfkit_meta_tags(body).inject({}) do |found, tag|
+ name = tag.attributes["name"].sub(/^#{PDFKit.configuration.meta_tag_prefix}/, '').to_sym
+ found.merge(name => tag.attributes["content"])
+ end
end
+
+ def pdfkit_meta_tags(body)
+ require 'rexml/document'
+ xml_body = REXML::Document.new(body)
+ found = []
+ xml_body.elements.each("html/head/meta") do |tag|
+ found << tag if tag.attributes['name'].to_s =~ /^#{PDFKit.configuration.meta_tag_prefix}/
+ end
+ found
+ rescue # rexml random crash on invalid xml
+ []
+ end
def style_tag_for(stylesheet)
"<style>#{File.read(stylesheet)}</style>"
end
@@ -85,10 +110,11 @@
end
end
def normalize_options(options)
normalized_options = {}
+
options.each do |key, value|
next if !value
normalized_key = "--#{normalize_arg key}"
normalized_options[normalized_key] = normalize_value(value)
end
@@ -101,11 +127,9 @@
def normalize_value(value)
case value
when TrueClass
nil
- when String
- value.match(/\s/) ? "\"#{value}\"" : value
else
value
end
end
\ No newline at end of file