Created
January 31, 2011 00:44
-
-
Save BinaryMuse/803483 to your computer and use it in GitHub Desktop.
A Liquid tag for Jekyll sites that allows embedding Gists and showing code for non-JavaScript enabled browsers and readers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'cgi' | |
require 'digest/md5' | |
require 'net/https' | |
require 'uri' | |
module Jekyll | |
class GistTag < Liquid::Tag | |
def initialize(tag_name, text, token) | |
super | |
@text = text | |
@cache_disabled = false | |
@cache_folder = File.expand_path "../_gist_cache", File.dirname(__FILE__) | |
end | |
def render(context) | |
if parts = @text.match(/([\d]*) (.*)/) | |
gist, file = parts[1].strip, parts[2].strip | |
script_url = script_url_for gist, file | |
code = get_cached_gist(gist, file) || get_gist_from_web(gist, file) | |
html_output_for script_url, code | |
else | |
"" | |
end | |
end | |
def html_output_for(script_url, code) | |
code = CGI.escapeHTML code | |
"<script src='#{script_url}'></script><noscript><pre><code>#{code}</code></pre></noscript>" | |
end | |
def script_url_for(gist_id, filename) | |
"https://gist.github.com/#{gist_id}.js?file=#{filename}" | |
end | |
def get_gist_url_for(gist, file) | |
"https://gist.github.com/raw/#{gist}/#{file}" | |
end | |
def cache(gist, file, data) | |
cache_file = get_cache_file_for gist, file | |
File.open(cache_file, "w") do |io| | |
io.write data | |
end | |
end | |
def get_cached_gist(gist, file) | |
return nil if @cache_disabled | |
cache_file = get_cache_file_for gist, file | |
File.read cache_file if File.exist? cache_file | |
end | |
def get_cache_file_for(gist, file) | |
bad_chars = /[^a-zA-Z0-9\-_.]/ | |
gist = gist.gsub bad_chars, '' | |
file = file.gsub bad_chars, '' | |
md5 = Digest::MD5.hexdigest "#{gist}-#{file}" | |
File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache" | |
end | |
def get_gist_from_web(gist, file) | |
gist_url = get_gist_url_for gist, file | |
raw_uri = URI.parse gist_url | |
https = Net::HTTP.new raw_uri.host, raw_uri.port | |
https.use_ssl = true | |
https.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
request = Net::HTTP::Get.new raw_uri.request_uri | |
data = https.request request | |
data = data.body | |
cache gist, file, data unless @cache_disabled | |
data | |
end | |
end | |
class GistTagNoCache < GistTag | |
def initialize(tag_name, text, token) | |
super | |
@cache_disabled = true | |
end | |
end | |
end | |
Liquid::Template.register_tag('gist', Jekyll::GistTag) | |
Liquid::Template.register_tag('gistnocache', Jekyll::GistTagNoCache) |
Dude this is something I have wanted for a loooong time. Thanks for sharing!
Now we need to get Github Pages to support something similar... ^_^
+1 on that
+1
In case anyone stumbles here wondering why the noscript
portion gets butchered, I think it's from the Markdown parser. (sorry, not really sure)
But you can fix the output by removing the noscript
tags and just hiding the pre
with javascript instead. That why the page will still show the code if javascript is off, say in RSS feed content for example.
The Markdown parser bug appears to be fixed by adding a newline character between the </script>
and <noscript>
:
<script src='#{script_url}'></script>\n<noscript><pre><code>#{code}</code></pre></noscript>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html for more information and details on the caching mechanism.