module Jekyll::Convertible

def [](property)

Returns the String value or nil if the property isn't included.

property - The String name of the property to retrieve.

Accessor for data properties by Liquid.
def [](property)
  if self.class::ATTRIBUTES_FOR_LIQUID.include?(property)
    send(property)
  else
    data[property]
  end
end

def asset_file?

that asset files use.
Returns true if the extname belongs to the set of extensions

Asset files include CoffeeScript files and Sass/SCSS files.
Determine whether the document is an asset file.
def asset_file?
  sass_file? || coffeescript_file?
end

def coffeescript_file?

Returns true if extname == .coffee, false otherwise.

Determine whether the document is a CoffeeScript file.
def coffeescript_file?
  ext == ".coffee"
end

def converters

Returns the Converter instance.

extension.
Determine which converter to use based on this convertible's
def converters
  renderer.converters
end

def defaults

def defaults
  @defaults ||= site.frontmatter_defaults.all(relative_path, type)
end

def do_layout(payload, layouts)

Returns nothing.

layouts - A Hash of {"name" => "layout"}.
payload - The site payload Drop or Hash.

Add any necessary layouts to this convertible document.
def do_layout(payload, layouts)
  self.output = renderer.tap do |doc_renderer|
    doc_renderer.layouts = layouts
    doc_renderer.payload = payload
  end.run
  Jekyll.logger.debug "Post-Render Hooks:", relative_path
  Jekyll::Hooks.trigger hook_owner, :post_render, self
ensure
  @renderer = nil # this will allow the modifications above to disappear
end

def hook_owner

returns the owner symbol for hook triggering
def hook_owner
  :pages if is_a?(Page)
end

def invalid_layout?(layout)

Returns true if the layout is invalid, false if otherwise

layout - the layout to check

Checks if the layout specified in the document actually exists
def invalid_layout?(layout)
  !data["layout"].nil? && layout.nil? && !(is_a? Jekyll::Excerpt)
end

def no_layout?

def no_layout?
  data["layout"] == "none"
end

def output_ext

e.g. ".html" for an HTML output file.
Returns the String extension for the output file.

Determine the extension depending on content_type.
def output_ext
  renderer.output_ext
end

def place_in_layout?

specifies `layout: none`
Returns false if the document is an asset file or if the front matter

Determine whether the file should be placed into layouts.
def place_in_layout?
  !(asset_file? || no_layout?)
end

def published?

Whether the file is published or not, as indicated in YAML front-matter
def published?
  !(data.key?("published") && data["published"] == false)
end

def read_yaml(base, name, opts = {})

rubocop:disable Metrics/AbcSize
Returns nothing.

opts - optional parameter to File.read, default at site configs
name - The String filename of the file.
base - The String path to the dir containing the file.

Read the YAML frontmatter.
def read_yaml(base, name, opts = {})
  filename = @path || site.in_source_dir(base, name)
  Jekyll.logger.debug "Reading:", relative_path
  begin
    self.content = File.read(filename, **Utils.merged_file_read_opts(site, opts))
    if content =~ Document::YAML_FRONT_MATTER_REGEXP
      self.content = Regexp.last_match.post_match
      self.data = SafeYAML.load(Regexp.last_match(1))
    end
  rescue Psych::SyntaxError => e
    Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
    raise e if site.config["strict_front_matter"]
  rescue StandardError => e
    Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
    raise e if site.config["strict_front_matter"]
  end
  self.data ||= {}
  validate_data! filename
  validate_permalink! filename
  self.data
end

def render_all_layouts(layouts, payload, info)

Returns nothing

info - the info for Liquid
payload - the payload for Liquid
layouts - a list of the layouts

Recursively render layouts
def render_all_layouts(layouts, payload, info)
  renderer.layouts = layouts
  self.output = renderer.place_in_layouts(output, payload, info)
ensure
  @renderer = nil # this will allow the modifications above to disappear
end

def render_liquid(content, payload, info, path)

Returns the converted content

info - the info for Liquid
payload - the payload for Liquid
content - the raw Liquid content to render

Render Liquid in the content
def render_liquid(content, payload, info, path)
  renderer.render_liquid(content, payload, info, path)
end

def render_with_liquid?

Returns true if the file has Liquid Tags or Variables, false otherwise.

Determine whether the file should be rendered with Liquid.
def render_with_liquid?
  return false if data["render_with_liquid"] == false
  Jekyll::Utils.has_liquid_construct?(content)
end

def renderer

def renderer
  @renderer ||= Jekyll::Renderer.new(site, self)
end

def sass_file?

Returns true if extname == .sass or .scss, false otherwise.

Determine whether the document is a Sass file.
def sass_file?
  Jekyll::Document::SASS_FILE_EXTS.include?(ext)
end

def to_liquid(attrs = nil)

Returns the Hash representation of this Convertible.

Convert this Convertible's data to a Hash suitable for use by Liquid.
def to_liquid(attrs = nil)
  further_data = \
    (attrs || self.class::ATTRIBUTES_FOR_LIQUID).each_with_object({}) do |attribute, hsh|
      hsh[attribute] = send(attribute)
    end
  Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
end

def to_s

Returns the contents as a String.
def to_s
  content || ""
end

def transform

Returns the transformed contents.

Transform the contents based on the content type.
def transform
  renderer.convert(content)
end

def type

Returns the type of self.

i.e., its classname downcase'd and to_sym'd.
The type of a document,
def type
  :pages if is_a?(Page)
end

def validate_data!(filename)

def validate_data!(filename)
  unless self.data.is_a?(Hash)
    raise Errors::InvalidYAMLFrontMatterError,
          "Invalid YAML front matter in #{filename}"
  end
end

def validate_permalink!(filename)

def validate_permalink!(filename)
  if self.data["permalink"] == ""
    raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
  end
end

def write(dest)

Returns nothing.

dest - The String path to the destination dir.

Write the generated page file to the destination directory.
def write(dest)
  path = destination(dest)
  FileUtils.mkdir_p(File.dirname(path))
  Jekyll.logger.debug "Writing:", path
  File.write(path, output, :mode => "wb")
  Jekyll::Hooks.trigger hook_owner, :post_write, self
end