class JekyllTitlesFromContent::Generator

Constants

COLLECTIONS_KEY
CONFIG_KEY
CONVERTER_CLASS
DOTDOTDOT_KEY
ENABLED_KEY
EXTRA_MARKUP_REGEX

Regex to strip extra markup still present after markdownify (footnotes at the moment).

STRIP_MARKUP_FILTERS
WORDS_KEY

Attributes

site[RW]

Public Class Methods

new(site) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 23
def initialize(site)
  @site = site
end

Public Instance Methods

generate(site) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 27
def generate(site)
  @site = site
  return if disabled?

  documents = site.pages
  documents = site.pages + site.docs_to_write if collections?

  documents.each do |document|
    next unless should_add_title?(document)
    next if document.is_a?(Jekyll::StaticFile)

    document.data["title"] = title_for(document)
  end
end
markdown?(document) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 50
def markdown?(document)
  markdown_converter.matches(document.extname)
end
markdown_converter() click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 54
def markdown_converter
  @markdown_converter ||= site.find_converter_instance(CONVERTER_CLASS)
end
should_add_title?(document) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 42
def should_add_title?(document)
  markdown?(document) && !title?(document)
end
title?(document) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 46
def title?(document)
  !inferred_title?(document) && !document.data["title"].nil?
end
title_for(document) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 65
def title_for(document)
  return document.data["title"] if title?(document)

  first_line = document.content.split("\n").find { |l| l unless strip_markup(l).empty? }
  return truncate(strip_markup(first_line), count, dotdotdot) unless first_line.nil?

  document.data["title"] # If we can't produce a title, we use the inferred one.
rescue ArgumentError => e
  raise e unless e.to_s.start_with?("invalid byte sequence in UTF-8")
end
truncate(string, count, cont = "") click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 58
def truncate(string, count, cont = "")
  spl = string.split
  tr = spl.first(count).join(" ")
  tr += cont if spl.length > count
  tr
end

Private Instance Methods

collections?() click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 92
def collections?
  option(COLLECTIONS_KEY) == true
end
count() click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 100
def count
  option(WORDS_KEY) || 5
end
disabled?() click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 88
def disabled?
  option(ENABLED_KEY) == false
end
dotdotdot() click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 96
def dotdotdot
  option(DOTDOTDOT_KEY) || ""
end
filters() click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 116
def filters
  @filters ||= JekyllTitlesFromContent::Filters.new(site)
end
inferred_title?(document) click to toggle source

Documents (posts and collection items) have their title inferred from the filename.

This is a terribly slow hack as we're reading the YAML for every document, but I can't find a better way of doing this as I can't find a method of obtaining the original unprocessed frontmatter.

# File lib/jekyll-titles-from-content/generator.rb, line 109
def inferred_title?(document)
  return false unless document.is_a?(Jekyll::Document)

  meta = read_yaml(File.dirname(document.path), File.basename(document.path))
  !meta.key?("title")
end
option(key) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 84
def option(key)
  site.config[CONFIG_KEY] && site.config[CONFIG_KEY][key]
end
read_yaml(base, name) click to toggle source

This is a slightly modified version of Jekyll::Convertible.read_yaml

# File lib/jekyll-titles-from-content/generator.rb, line 121
def read_yaml(base, name)
  filename = File.join(base, name)

  begin
    content = File.read(filename)
    if content =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
      content = $POSTMATCH # rubocop:disable Lint/UselessAssignment
      data = SafeYAML.load(Regexp.last_match(1))
    end
  rescue 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

  data || {}
end
strip_markup(string) click to toggle source
# File lib/jekyll-titles-from-content/generator.rb, line 78
def strip_markup(string)
  STRIP_MARKUP_FILTERS.reduce(string) do |memo, method|
    filters.public_send(method, memo)
  end.gsub(EXTRA_MARKUP_REGEX, "")
end