Jekyll插件:嵌入github Gist Jan 27th, 2013 | Comments gist是gtihub的一个代码块功能,用来粘贴一些比较长的代码还是挺有用的。 github page可以直接嵌入gist,并且能显示高亮。 不过我不想太依赖gist,所以修改成使用pygments高亮的方式。 看看下面gist_tag.rb这个插件的效果: require 'cgi' require 'digest/md5' require 'net/https' require 'uri' module Jekyll class GistTag < Liquid::Tag include Liquid::StandardFilters def initialize(tag_name, text, token) super @text = text @options = {:encoding => "utf-8"} @cache_disabled = false @cache_folder = File.expand_path "../_gist_cache", File.dirname(__FILE__) FileUtils.mkdir_p @cache_folder end def render(context) if parts = @text.match(/([\d]*) lang=(.+) (.*)/) gist, @lang, file = parts[1].strip, parts[2].strip, parts[3].strip script_url = script_url_for gist, file code = get_cached_gist(gist, file) || get_gist_from_web(gist, file) context.registers[:site].pygments html_output_for context, script_url, code else "" end end def html_output_for(context, script_url, code) if context.registers[:site].pygments output = add_code_tags(Pygments.highlight(code, :lexer => @lang, :options => @options)) else render_codehighlighter(code) end end def add_code_tags(code) # Add nested <code> tags to code blocks code = code.sub(/<pre>/,'<pre><code class="#{@lang}">') code = code.sub(/<\/pre>/,"</code></pre>") end def render_codehighlighter(code) #The div is required because RDiscount blows ass <<-HTML <div> <pre><code class='#{@lang}'>#{h(code).strip}</code></pre> </div> HTML 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://raw.github.com/gist/#{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)