-
-
Save imathis/1027674 to your computer and use it in GitHub Desktop.
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__) | |
FileUtils.mkdir_p @cache_folder | |
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><div><noscript><pre><code>#{code}</code></pre></noscript></div>" | |
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) |
If you use RDiscount you shouldn't have that problem. Maruku seems to have a hard time with HTML mixed into markdown.
Anyway to port this over to a non jekyll based platform?
@esparkman I suppose that depends on the platform but theoretically yes, you should be able to build this feature for other platforms.
You can also embed private gists if you change line 17 to:
if parts = @text.match(/([\w]*) (.*)/)
This is because private Gist ID's not only contain digits but also alpha characters as well.
You could also do a pull against my fork (git://gist.github.com/3706958.git) if you have a local clone. :)
While playing around with embedding gists, I realized gists could be obtained in json format. The url is almost identical to the javascript url:
https://gist.github.com/jehoshua02/4681039.json?file=.gitignore
The html content is right there in the "div"
property of the json string.
I've also been having problems with the gist tag in octopress. Even though I specify a file, all files in the gist are output. Very rarely do I want to embed every file from a gist, but would rather embed one file, explain it, embed another file, etc.
def get_gist_url_for(gist, filename)
file = filename == '' ? '' : "/#{filename}"
"https://raw.github.com/gist/#{gist}#{file}"
end
Without adding that second line, gist tags created with just an id and no filename don't work.
Works great, thanks!
The gist URL has changed as noted here (or with the urls generated for a gist):
Same problem here. Any ideas on how to fix this without changing all the posts again?
Here's the fix: https://gist.github.com/creativepsyco/6821946 Changed the plugin to read the config and adjust the url accordingly . This means you can embed your own gists only
you would need to add your github username to Jekyll Config file though.
In _config.yml
set github_user
to your github username
@imathis Is it possible for you to fork the jekyll-project and replace the built in gist tag with your version? I think that would be a great improvement for jekyll!
jekyll now has gist build-in support, but the usage is :
# Gist Liquid Tag
#
# Example:
# {% gist username/1234567 %}
# {% gist username/1234567 file.rb %}
see https://github.com/jekyll/jekyll/blob/master/lib/jekyll/tags/gist.rb
but……It's realy ugly!
Thanks for your comment.
I once deleted my gist and created a public gist to get a numeric ID.
But I couldn't get it.
So I modified the following code.
/usr/local/rvm/gems/ruby-2.1.1/gems/jekyll-1.0.2/lib/jekyll/tags/gist.rb
# diff gist.rb.org gist.rb 10c10 < if tag_contents = @markup.strip.match(/\A(\d+) ?(\S*)\Z/) --- > if tag_contents = @markup.strip.match(/\A([0-9a-fA-F]+) ?(\S*)\Z/)
The following is my setup.
ruby 2.1.1p76 jekyll 1.0.2
Can you use this tag to embed files in GitHub repos (not gist files) into posts? If so, how would ya?
I've updated this to work as originally described, no need to include a github username, and works with current hex gist ids.
Thanks. Using your code and example, I get the following error when I run
jekyll
If I run
jekyll --server
I can browse to the post. All my content from below the gist tag is lost, but the first half and the gist bit appears okay.