aboutsummaryrefslogtreecommitdiff
path: root/_plugins
diff options
context:
space:
mode:
Diffstat (limited to '_plugins')
-rw-r--r--_plugins/filters.rb25
-rw-r--r--_plugins/meta.rb67
-rw-r--r--_plugins/toc.rb62
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)
+