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