diff options
Diffstat (limited to '_plugins')
-rw-r--r-- | _plugins/filters.rb | 25 | ||||
-rw-r--r-- | _plugins/meta.rb | 67 | ||||
-rw-r--r-- | _plugins/toc.rb | 62 |
3 files changed, 154 insertions, 0 deletions
diff --git a/_plugins/filters.rb b/_plugins/filters.rb new file mode 100644 index 0000000..78eb04f --- /dev/null +++ b/_plugins/filters.rb @@ -0,0 +1,25 @@ +module Filters + def datefmt(input) + return input.strftime("%F") + end + + def sentence_join(items, fallback = "") + return fallback if items == nil or items.length == 0 + return "#{items[0]}" if items.length == 1 + return "#{items[0..-2].join(", ")} and #{items[-1]}" + end + + def plural(num, counter) + return "#{num} #{counter}#{num == 1 ? '' : 's'}" + end + + def post_sort(posts, sort_by) + # date (reverse chronological) + return posts.sort_by{ |post| -post.data['date'].to_i } if sort_by == "date" + # title (case insensitive) + return posts.sort_by{ |post| post.data['title'].downcase } if sort_by == "title" + end +end + +Liquid::Template.register_filter(Filters) + diff --git a/_plugins/meta.rb b/_plugins/meta.rb new file mode 100644 index 0000000..0e25871 --- /dev/null +++ b/_plugins/meta.rb @@ -0,0 +1,67 @@ +class Meta < Jekyll::Generator + def generate(site) + # convert yaml @0123456789 (unix timestamps) into ruby Date + site.data = parse_unix_dates(site.data) + + posts = site.collections['items'] + for page in posts do + # convert generated page metadata and add directly to `page.meta` in liquid + page.data['meta'] = transform_data(site, page.data['slug']) + + # set page.authors to author metadata from git+yaml + page.data['authors'] = site.data['authors'].filter do |author| + author['git'].intersect?(page.data['meta']['authors']) + end + + # set page.date to generated date_initial + page.data['date'] = page.data['meta']['date'] + end + + # count tags on all posts + site.data['tags'] = count_tags(posts) + end + + def parse_unix_dates(data) + # recurse deeper + return data.transform_values { |val| parse_unix_dates(val) } if data.is_a? Hash + return data.map { |val| parse_unix_dates(val) } if data.is_a? Array + + # convert strings matching regex + return Time.at(Integer(data[1..])) if data.is_a? String and data =~ /^@\d+$/ + + # base case + return data + end + + def transform_data(site, slug) + data = site.data['post'][slug] + data['git_log'] = data['git_log'].sort { |c| c['date'].to_i } + + git_log = data['git_log'].filter do |commit| + !site.data['git']['ignore_commits'].include?(commit['hash']) + end + + data['authors'] = git_log.map{ |c| c['author'] }.uniq + data['date_initial'] = git_log.first['date'] + data['date'] = git_log.last['date'] + data['edits'] = git_log.length - 1 # original commit is not an edit + return data + end + + def count_tags(posts) + tags = {} + + # tally tags + for post in posts do + for tag in post.data['tags'] do + tags[tag] = tags.fetch(tag, 0) + 1 + end + end + + # sort by post count descending + tags = tags.sort_by {|key,value| -value} + + return tags + end +end + diff --git a/_plugins/toc.rb b/_plugins/toc.rb new file mode 100644 index 0000000..09ef946 --- /dev/null +++ b/_plugins/toc.rb @@ -0,0 +1,62 @@ +require 'nokogiri' + +class TOC < Liquid::Tag + def render context + # load HTML into nokogiri + html = context.registers[:page]['content'] + doc = Nokogiri::HTML(html) + + # enumerate over all h1-4 headings + @els = doc.css("h1, h2, h3, h4") + toc = output_toc() + return '' if toc.empty? + return '<aside id="toc" class="plainlink">%s</aside>' % [ toc ] + end + + def output_toc + # empty toc (this check prevents crash) + return "" if @els.length == 0 + + output = '<ul>' + + current_level = el_level(@els[0]) + + while @els.length > 0 + el = @els[0] + el_next = @els[1] + level = el_level(el) + level_next = el_level(el_next || el) # || el to prevent crash on end of list + + if level >= level_next + output += '<li>' + else + output += '<li class="stub"><details>' + output += '<summary>' + end + + output += '<a href="#%s">%s</a>' % [ el['id'], el.inner_html ] + @els.shift() + + if level >= level_next + output += '</li>' + else + output += '</summary>' + output += output_toc + output += '</details></li>' + end + + break if level_next < level + end + + output += '</ul>' + + return output + end + + def el_level el + return Integer(el.name[1..]) + end +end + +Liquid::Template.register_tag('toc', TOC) + |