Skip to content

Instantly share code, notes, and snippets.

@kurtkilgor kurtkilgor/include_poem.rb
Last active Aug 29, 2015

Embed
What would you like to do?
Octopress plugin for including poem translations in a page.
# Title: Include Poem Tag for Jekyll
# Author: Max Eskin http://maxeskin.com
# Description: Import files on your filesystem into any blog post as embedded text snippets with line numbers.
#
# Syntax {% include_poem key=value ... %}
#
# Keys:
# left - Specifies file for left column (use this if only a single column is desired)
# right - File for right column
# title - Title
#
# Example 1:
# {% include_poem left=raven.txt %}
#
# This will import raven.txt from source/raven.txt
#
# Example 2:
# You can also include an optional title for the <figcaption>
#
# {% include_poem title="The Raven" left=raven.txt %}
#
# will output a figcaption with the title: The Raven
#
require './plugins/raw'
require 'pathname'
module Jekyll
class IncludePoemTag < Liquid::Tag
include TemplateWrapper
def initialize(tag_name, markup, tokens)
h = Hash[markup.scan(/(?:"(?:\\.|[^"])*"|[^" ])+/).map { |l| l.chomp.split('=', 2) }]
@title = h.fetch('title', '').gsub('"', '')
@file = h.fetch('left', '')
@right_file = h.fetch('right', nil)
super
end
def read_poem(context, file, title)
site = context.registers[:site]
converter = site.getConverterImpl(::Jekyll::MarkdownConverter)
poem = converter.convert(file.read)
poem.gsub!(/<\/?p>/, '')
footnote_start_string = '<div class="footnotes">'
footnote_index = poem.index(footnote_start_string)
footnote = ''
if footnote_index
clean_title = title.gsub(/[^a-zA-Z0-9]/, '')
footnote_start = footnote_index + footnote_start_string.length
footnote = poem[footnote_start..-10]
poem = poem[0..footnote_index-1]
poem.gsub!('"#fn:', '"#' + clean_title + 'fn:')
footnote.gsub!('"fn:', '"' + clean_title + 'fn:')
poem.gsub!('"fnref:', '"' + clean_title + 'fnref:')
footnote.gsub!('"#fnref:', '"#' + clean_title + 'fnref:')
footnote.gsub!('<hr/>', '')
end
return poem, footnote
end
def render(context)
poem_path = (Pathname.new(context.registers[:site].source)).expand_path
file = poem_path + @file
right_file = ''
if @right_file
right_file = poem_path + @right_file
end
unless file.file?
return "file #{file} could not be found"
end
if @right_file && !right_file.file?
return "file #{right_file} could not be found"
end
Dir.chdir(poem_path) do
title = @title != '' ? "#{@title}" : @file
poem, footnote = read_poem(context, file, title)
right_poem = ''
right_footnote = ''
if @right_file
right_poem, right_footnote = read_poem(context, right_file, title + '2')
end
url = "{@file}"
source = "<figure class='code'>\n\t<figcaption><span>#{title}</span></figcaption>"
table = tableize_poem(poem, right_poem, footnote + right_footnote)
source += "#{table}\n</figure>"
safe_wrap(source)
end
end
def tableize_poem (str, right_str='', footnotes='')
table = '<div class="highlight"><table style="border-collapse:separate">'
lines = 0
total_rows = str.lines.count
total_cols = right_str ? 4 : 2
str.lines.each_with_index do |line, index|
number = ''
empty_line = line.strip == ''
if !empty_line
lines = lines+1
number = lines
end
table += '<tr>'
# If the line is empty, we want to preserve the default vertical padding to achieve a blank space
number_style = empty_line ? "style='vertical-align:top'" : "style='vertical-align:top;padding-top:0;padding-bottom:0'"
table += "<td class='line-numbers' #{number_style}>#{number}</td>"
left_style = right_str == '' ? "style='vertical-align:top'" : "style='vertical-align:top; width:50%'"
table += "<td class='code' #{left_style}>#{format_line(line)}</td>"
if right_str != ''
# Divider
if index == 0
table += "<td rowspan=#{total_rows} style='background-color:#cacccd;border-color:#2c3e50;border-style:solid;border-width:5px;' width='1px'></td>"
end
right_line = right_str.lines[index]
table += "<td class='code' style='vertical-align:top'>#{format_line(right_line)}</td>"
end
table += "</tr>\n"
end
footnote_row = ''
if footnotes != ''
footnote_row = "<tr><td colspan=#{total_cols} class='code-title' style='border-top-left-radius:0px; border-top-right-radius:0px; text-align:left'>#{footnotes}</td></tr>"
end
table += "#{footnote_row}</table></div>"
end
def format_line(line)
"<pre style='font-family:inherit; word-break:normal' class='line'>#{line.strip}</pre>"
end
end
end
Liquid::Template.register_tag('include_poem', Jekyll::IncludePoemTag)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.