# @author Copyright 2022 {https://www.mslinn.com Michael Slinn}
require 'jekyll_draft'
require 'jekyll_plugin_logger'
require 'jekyll_plugin_support'
require 'yaml'
require_relative 'jekyll_outline/version'
module Outline
PLUGIN_NAME = 'outline'.freeze
# Interleaves with docs
class Header
attr_accessor :order, :title
def initialize(yaml)
@order = yaml[0]
@published = true
@title = yaml[1]
end
def to_s
<<~END_STR
#{title}
END_STR
end
end
class OutlineTag < JekyllSupport::JekyllBlock
include JekyllOutlineVersion
FIXNUM_MAX = (2**((0.size * 8) - 2)) - 1
def render_impl(text)
@collection_name = argument_string.strip
abort 'OutlineTag: collection_name was not specified' unless @collection_name
headers = make_headers(super) # Process the block content.
collection = headers + obtain_docs(@collection_name)
<<~HEREDOC
#{make_entries(collection).join("\n")}
HEREDOC
end
private
def header?(variable)
variable.instance_of?(Header)
end
def make_headers(content)
yaml = YAML.safe_load content
yaml.map { |entry| Header.new entry }
end
def make_entries(collection)
sorted = collection.sort_by(&obtain_order)
pruned = remove_empty_headers(sorted)
pruned.map do |entry|
if entry.instance_of? Header
<<~END_ENTRY
#{entry}
END_ENTRY
else
date = entry.data['last_modified_at'] # "%Y-%m-%d"
draft = Jekyll::Draft.draft_html(entry)
<<~END_ENTRY
#{date} #{entry.data['title']}#{draft}
END_ENTRY
end
end
end
# Ignores files called index.html
def obtain_docs(collection_name)
abort "#{@collection_name} is not a valid collection." unless @site.collections.key? @collection_name
@site
.collections[collection_name]
.docs
.reject { |doc| doc.path.end_with? 'index.html' }
end
# Sort entries without an order property at the end
def obtain_order
proc do |entry|
if entry.respond_to? :data
entry.data.key?('order') ? entry.data['order'] : FIXNUM_MAX
else
entry.order
end
end
end
def remove_empty_headers(array)
i = 0
while i < array.length - 1
if header?(array[i]) && header?(array[i + 1])
array.delete_at(i)
else
i += 1
end
end
array.delete_at(array.length - 1) if header?(array.last)
array
end
JekyllPluginHelper.register(self, PLUGIN_NAME)
end
end