plugins/gist_tag.rb
ab29d45a
 # A Liquid tag for Jekyll sites that allows embedding Gists and showing code for non-JavaScript enabled browsers and readers.
 # by: Brandon Tilly
 # Source URL: https://gist.github.com/1027674
e4c2d579
 # Post http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html
 #
ab29d45a
 # Example usage: {% gist 1027674 gist_tag.rb %} //embeds a gist for this plugin
e4c2d579
 
ab29d45a
 require 'cgi'
e4c2d579
 require 'digest/md5'
 require 'net/https'
 require 'uri'
 
 module Jekyll
   class GistTag < Liquid::Tag
     def initialize(tag_name, text, token)
       super
ab29d45a
       @text           = text
       @cache_disabled = false
       @cache_folder   = File.expand_path "../_gist_cache", File.dirname(__FILE__)
       FileUtils.mkdir_p @cache_folder
e4c2d579
     end
 
     def render(context)
ab29d45a
       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
e4c2d579
 
ab29d45a
     def html_output_for(script_url, code)
       code = CGI.escapeHTML code
       <<-HTML
 <script src='#{script_url}'></script>
 <noscript><pre><code>#{code}</code></pre></noscript>
       HTML
     end
e4c2d579
 
ab29d45a
     def script_url_for(gist_id, filename)
       "https://gist.github.com/#{gist_id}.js?file=#{filename}"
e4c2d579
     end
 
     def get_gist_url_for(gist, file)
ab29d45a
       "https://raw.github.com/gist/#{gist}/#{file}"
e4c2d579
     end
 
ab29d45a
     def cache(gist, file, data)
       cache_file = get_cache_file_for gist, file
       File.open(cache_file, "w") do |io|
         io.write data
e4c2d579
       end
     end
 
     def get_cached_gist(gist, file)
ab29d45a
       return nil if @cache_disabled
       cache_file = get_cache_file_for gist, file
       File.read cache_file if File.exist? cache_file
e4c2d579
     end
 
     def get_cache_file_for(gist, file)
ab29d45a
       bad_chars = /[^a-zA-Z0-9\-_.]/
       gist      = gist.gsub bad_chars, ''
       file      = file.gsub bad_chars, ''
       md5       = Digest::MD5.hexdigest "#{gist}-#{file}"
e4c2d579
       File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache"
     end
 
     def get_gist_from_web(gist, file)
ab29d45a
       gist_url          = get_gist_url_for gist, file
       raw_uri           = URI.parse gist_url
       https             = Net::HTTP.new raw_uri.host, raw_uri.port
e4c2d579
       https.use_ssl     = true
       https.verify_mode = OpenSSL::SSL::VERIFY_NONE
ab29d45a
       request           = Net::HTTP::Get.new raw_uri.request_uri
       data              = https.request request
e4c2d579
       data              = data.body
ab29d45a
       cache gist, file, data unless @cache_disabled
e4c2d579
       data
     end
   end
 
   class GistTagNoCache < GistTag
     def initialize(tag_name, text, token)
       super
ab29d45a
       @cache_disabled = true
e4c2d579
     end
   end
 end
 
 Liquid::Template.register_tag('gist', Jekyll::GistTag)
 Liquid::Template.register_tag('gistnocache', Jekyll::GistTagNoCache)