diff --git a/.rubocop.yml b/.rubocop.yml index 4193f4b4..168e779a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,7 +4,6 @@ AllCops: Include: - lib/**/*.rb Exclude: - - lib/jekyll/renderer.rb - bin/**/* - exe/**/* - benchmark/**/* diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 11d5fa86..34741c8f 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -78,7 +78,7 @@ module Jekyll # # Returns the transformed contents. def transform - _renderer.transform + _renderer.convert(content) end # Determine the extension depending on content_type. diff --git a/lib/jekyll/page.rb b/lib/jekyll/page.rb index 324a867d..2fb899cc 100644 --- a/lib/jekyll/page.rb +++ b/lib/jekyll/page.rb @@ -127,12 +127,12 @@ module Jekyll # layouts - The Hash of {"name" => "layout"}. # site_payload - The site payload Hash. # - # Returns nothing. + # Returns String rendered page. def render(layouts, site_payload) - site_payload["page"] = to_liquid - site_payload["paginator"] = pager.to_liquid - - do_layout(site_payload, layouts) + self.output = _renderer.tap do |renderer| + renderer.layouts = layouts + renderer.payload = site_payload + end.run end # The path to the source file diff --git a/lib/jekyll/renderer.rb b/lib/jekyll/renderer.rb index 749882bf..3a4aedc9 100644 --- a/lib/jekyll/renderer.rb +++ b/lib/jekyll/renderer.rb @@ -33,50 +33,44 @@ module Jekyll # Determine which converters to use based on this document's # extension. # - # Returns an array of Converter instances. + # Returns Array of Converter instances. def converters @converters ||= site.converters.select { |c| c.matches(document.extname) }.sort end # Determine the extname the outputted file should have # - # Returns the output extname including the leading period. + # Returns String the output extname including the leading period. def output_ext @output_ext ||= (permalink_ext || converter_output_ext) end - ###################### - ## DAT RENDER THO - ###################### - + # Prepare payload and render the document + # + # Returns String rendered document output def run Jekyll.logger.debug "Rendering:", document.relative_path - payload["page"] = document.to_liquid - - if document.respond_to? :pager - payload["paginator"] = document.pager.to_liquid - end - - if document.is_a?(Document) && document.collection.label == "posts" - payload["site"]["related_posts"] = document.related_posts - else - payload["site"]["related_posts"] = nil - end - - # render and transform content (this becomes the final content of the object) - payload["highlighter_prefix"] = converters.first.highlighter_prefix - payload["highlighter_suffix"] = converters.first.highlighter_suffix + assign_pages! + assign_related_posts! + assign_highlighter_options! Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path document.trigger_hooks(:pre_render, payload) + render_document + end + + # Render the document. + # + # Returns String rendered document output + # rubocop: disable AbcSize + def render_document info = { + :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload["page"] } } - output = document.content - if document.render_with_liquid? Jekyll.logger.debug "Rendering Liquid:", document.relative_path output = render_liquid(output, payload, info, document.path) @@ -88,21 +82,16 @@ module Jekyll if document.place_in_layout? Jekyll.logger.debug "Rendering Layout:", document.relative_path - place_in_layouts( - output, - payload, - info - ) - else - output + output = place_in_layouts(output, payload, info) end - end - # Convert the given content using the converters which match this renderer's document. + output + end + # rubocop: enable AbcSize + + # Convert the document using the converters which match this renderer's document. # - # content - the raw, unconverted content - # - # Returns the converted content. + # Returns String the converted content. def convert(content) converters.reduce(content) do |output, converter| begin @@ -124,7 +113,7 @@ module Jekyll # info - # path - (optional) the path to the file, for use in ex # - # Returns the content, rendered by Liquid. + # Returns String the content, rendered by Liquid. def render_liquid(content, payload, info, path = nil) template = site.liquid_renderer.file(path).parse(content) template.warnings.each do |e| @@ -144,26 +133,18 @@ module Jekyll # # layout - the layout to check # - # Returns true if the layout is invalid, false if otherwise + # Returns Boolean true if the layout is invalid, false if otherwise def invalid_layout?(layout) !document.data["layout"].nil? && layout.nil? && !(document.is_a? Jekyll::Excerpt) end - # Render layouts and place given content inside. + # Render layouts and place document content inside. # - # content - the content to be placed in the layout - # - # - # Returns the content placed in the Liquid-rendered layouts + # Returns String rendered content def place_in_layouts(content, payload, info) output = content.dup layout = layouts[document.data["layout"]] - - Jekyll.logger.warn( - "Build Warning:", - "Layout '#{document.data["layout"]}' requested in "\ - "#{document.relative_path} does not exist." - ) if invalid_layout? layout + validate_layout(layout) used = Set.new([layout]) @@ -171,33 +152,87 @@ module Jekyll payload["layout"] = nil while layout - payload["content"] = output - payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) + output = render_layout(output, layout, info) + add_regenerator_dependencies(layout) - output = render_liquid( - layout.content, - payload, - info, - layout.relative_path - ) - - # Add layout to dependency tree - site.regenerator.add_dependency( - site.in_source_dir(document.path), - site.in_source_dir(layout.path) - ) if document.write? - - if (layout = layouts[layout.data["layout"]]) + if (layout = site.layouts[layout.data["layout"]]) break if used.include?(layout) used << layout end end - output end + # Checks if the layout specified in the document actually exists + # + # layout - the layout to check + # Returns nothing private + def validate_layout(layout) + Jekyll.logger.warn( + "Build Warning:", + "Layout '#{document.data["layout"]}' requested "\ + "in #{document.relative_path} does not exist." + ) if invalid_layout?(layout) + end + # Render layout content into document.output + # + # Returns String rendered content + private + def render_layout(output, layout, info) + payload["content"] = output + payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) + + render_liquid( + layout.content, + payload, + info, + layout.relative_path + ) + end + + private + def add_regenerator_dependencies(layout) + site.regenerator.add_dependency( + site.in_source_dir(document.path), + site.in_source_dir(layout.path) + ) if document.write? + end + + # Set page content to payload and assign pager if document has one. + # + # Returns nothing + private + def assign_pages! + payload["page"] = document.to_liquid + payload["paginator"] = if document.respond_to?(:pager) + document.pager.to_liquid + end + end + + # Set related posts to payload if document is a post. + # + # Returns nothing + private + def assign_related_posts! + if document.is_a?(Document) && document.collection.label == "posts" + payload["site"]["related_posts"] = document.related_posts + else + payload["site"]["related_posts"] = nil + end + end + + # Set highlighter prefix and suffix + # + # Returns nothing + private + def assign_highlighter_options! + payload["highlighter_prefix"] = converters.first.highlighter_prefix + payload["highlighter_suffix"] = converters.first.highlighter_suffix + end + + private def permalink_ext if document.permalink && !document.permalink.end_with?("/") permalink_ext = File.extname(document.permalink) @@ -205,6 +240,7 @@ module Jekyll end end + private def converter_output_ext if output_exts.size == 1 output_exts.last @@ -213,6 +249,7 @@ module Jekyll end end + private def output_exts @output_exts ||= converters.map do |c| c.output_ext(document.extname)