require 'tmpdir' require 'digest/md5' require File.dirname(__FILE__) + '/helper.rb' module Jekyll module PDF class Partial extend Forwardable include Helper attr_accessor :doc attr_accessor :partial attr_accessor :write attr_accessor :content, :ext attr_writer :output def_delegators :@doc, :site, :name, :ext, :relative_path, :extname, :render_with_liquid?, :collection, :related_posts # Initialize this Partial instance. # # doc - The Document. # # Returns the new Partial. def initialize(doc, partial) self.doc = doc self.partial = partial self.content = build_partial(partial) end # Fetch YAML front-matter data from related doc, without layout key # # Returns Hash of doc data def data @data ||= doc.data.dup @data.delete('layout') @data end def trigger_hooks(*); end def path File.join(doc.path, partial) end def id File.basename(path, File.extname(path)) + '-' + Digest::MD5.hexdigest(to_s) + File.extname(path) end # Returns the cache directory def dir @dir ||= cache_dir end def to_s output || content end def to_liquid doc.data[partial] = nil @to_liquid ||= doc.to_liquid doc.data[partial] = self @to_liquid end # Returns the shorthand String identifier of this doc. def inspect "" end def output @output ||= Renderer.new(doc.site, self, site.site_payload).run end # generate temp file & set output to it's path def write tempfile = File.absolute_path(File.join(dir, id)) unless File.exist?(tempfile) FileUtils.mkdir_p(File.dirname(tempfile)) unless File.exist?(File.dirname(tempfile)) fix_relative_paths File.open(tempfile, 'w') { |f| f.write(to_s) } end @output = tempfile # store path for cleanup site.data[:jekyll_pdf_partials] ||= [] site.data[:jekyll_pdf_partials] << to_s end def place_in_layout? false end protected def cache_dir return site.config['pdf']['cache'] if !site.config['pdf'].nil? && site.config['pdf'].key?('cache') # Use jekyll-assets cache directory if it exists cache_dir = site.config['assets']['cache'] || '.asset-cache' unless site.config['assets'].nil? File.join(cache_dir || Dir.tmpdir, 'pdf') end # Internal: Generate partial html # # Partials are rendered same time as content is rendered. # # Returns partial html String def build_partial(path) # vars to insert into partial vars = %w[frompage topage page webpage section subsection subsubsection] doc.data['pdf'] = {} vars.each { |var| doc.data['pdf'][var] = "" } # JavaScript to replace var placeholders with content script = "\n" # Parse & render content = File.read(File.join('_includes', path)) # Add replacer script to body if content =~ /<\/body>/i content[/(<\/body>)/i] = script + content[/(<\/body>)/i] else Jekyll.logger.warn <<-eos Couldn't find in #{path}. Make sure your partial is a properly formatted HTML document (including DOCTYPE) e.g. Page {{ pdf.page }} of {{ pdf.topage }} eos # No body found - insert html into default template content = %( #{output} #{script} ) end content end end end end