class PDFKit

Constants

VERSION

Attributes

configuration[RW]
renderer[R]
source[RW]
stylesheets[RW]

Public Class Methods

configure() { |configuration| ... } click to toggle source
# File lib/pdfkit/configuration.rb, line 86
def self.configure
  yield(configuration)
end
new(url_file_or_html, options = {}) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 32
def initialize(url_file_or_html, options = {})
  @source = Source.new(url_file_or_html)

  @stylesheets = []

  options = PDFKit.configuration.default_options.merge(options)
  options.delete(:quiet) if PDFKit.configuration.verbose?
  options.merge! find_options_in_meta(url_file_or_html) unless source.url?
  @root_url = options.delete(:root_url)
  @protocol = options.delete(:protocol)
  @renderer = WkHTMLtoPDF.new options
  @renderer.normalize_options

  raise NoExecutableError unless File.exist?(PDFKit.configuration.wkhtmltopdf)
end

Public Instance Methods

command(path = nil) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 48
def command(path = nil)
  args = [*executable]
  args.concat(@renderer.options_for_command)
  args << @source.to_input_for_command
  args << (path ? path.to_s : '-')
  args
end
executable() click to toggle source
# File lib/pdfkit/pdfkit.rb, line 61
def executable
  PDFKit.configuration.executable
end
options() click to toggle source
# File lib/pdfkit/pdfkit.rb, line 56
def options
  # TODO(cdwort,sigmavirus24): Replace this with an attr_reader for @renderer instead in 1.0.0
  @renderer.options
end
to_file(path) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 83
def to_file(path)
  self.to_pdf(path)
  File.new(path)
end
to_pdf(path=nil) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 65
def to_pdf(path=nil)
  preprocess_html
  append_stylesheets

  invoke = command(path)

  result = IO.popen(invoke, "wb+") do |pdf|
    pdf.puts(@source.to_s) if @source.html?
    pdf.close_write
    pdf.gets(nil) if path.nil?
  end

  # $? is thread safe per
  # http://stackoverflow.com/questions/2164887/thread-safe-external-process-in-ruby-plus-checking-exitstatus
  raise ImproperWkhtmltopdfExitStatus, invoke if empty_result?(path, result) || !successful?($?)
  return result
end

Protected Instance Methods

append_stylesheets() click to toggle source
# File lib/pdfkit/pdfkit.rb, line 126
def append_stylesheets
  raise ImproperSourceError, 'Stylesheets may only be added to an HTML source' if stylesheets.any? && !@source.html?

  stylesheets.each do |stylesheet|
    if @source.to_s.match(/<\/head>/)
      @source = Source.new(@source.to_s.gsub(/(<\/head>)/) {|s|
        style_tag_for(stylesheet) + (s.respond_to?(:html_safe) ? s.html_safe : s)
      })
    else
      @source.to_s.insert(0, style_tag_for(stylesheet))
    end
  end
end
empty_result?(path, result) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 150
def empty_result?(path, result)
  (path && File.size(path) == 0) || (path.nil? && result.to_s.strip.empty?)
end
find_options_in_meta(content) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 90
def find_options_in_meta(content)
  # Read file if content is a File
  content = content.read if content.is_a?(File) || content.is_a?(Tempfile)

  found = {}
  content.scan(/<meta [^>]*>/) do |meta|
    if meta.match(/name=["']#{PDFKit.configuration.meta_tag_prefix}/)
      name = meta.scan(/name=["']#{PDFKit.configuration.meta_tag_prefix}([^"']*)/)[0][0].split
      found[name] = meta.scan(/content=["']([^"'\\]+)["']/)[0][0]
    end
  end

  tuple_keys = found.keys.select { |k| k.is_a? Array }
  tuple_keys.each do |key|
    value = found.delete key
    new_key = key.shift
    found[new_key] ||= {}
    found[new_key][key] = value
  end

  found
end
preprocess_html() click to toggle source
# File lib/pdfkit/pdfkit.rb, line 119
def preprocess_html
  if @source.html?
    processed_html = PDFKit::HTMLPreprocessor.process(@source.to_s, @root_url, @protocol)
    @source = Source.new(processed_html)
  end
end
style_tag_for(stylesheet) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 113
def style_tag_for(stylesheet)
  style = "<style>#{File.read(stylesheet)}</style>"
  style = style.html_safe if style.respond_to?(:html_safe)
  style
end
successful?(status) click to toggle source
# File lib/pdfkit/pdfkit.rb, line 140
def successful?(status)
  return true if status.success?

  # Some of the codes: https://code.google.com/p/wkhtmltopdf/issues/detail?id=1088
  # returned when assets are missing (404): https://code.google.com/p/wkhtmltopdf/issues/detail?id=548
  return true if status.exitstatus == 2 && @renderer.error_handling?

  false
end