require 'cgi'
require 'net/http'
require 'octokit'
Net::OpenTimeout = Class.new(RuntimeError) unless Net.const_defined?(:OpenTimeout)
Net::ReadTimeout = Class.new(RuntimeError) unless Net.const_defined?(:ReadTimeout)
module Jekyll
module Gist
class GistTag < Liquid::Tag
def render(context)
@encoding = context.registers[:site].config['encoding'] || 'utf-8'
@settings = context.registers[:site].config['gist']
if tag_contents = determine_arguments(@markup.strip)
gist_id, filename = tag_contents[0], tag_contents[1]
if context_contains_key?(context, gist_id)
gist_id = context[gist_id]
end
if context_contains_key?(context, filename)
filename = context[filename]
end
noscript_tag = gist_noscript_tag(gist_id, filename)
script_tag = gist_script_tag(gist_id, filename)
"#{noscript_tag}#{script_tag}"
else
raise ArgumentError.new <<-eos
Syntax error in tag 'gist' while parsing the following markup:
#{@markup}
Valid syntax:
{% gist user/1234567 %}
{% gist user/1234567 foo.js %}
{% gist 28949e1d5ee2273f9fd3 %}
{% gist 28949e1d5ee2273f9fd3 best.md %}
eos
end
end
private
def determine_arguments(input)
matched = input.match(/\A([\S]+|.*(?=\/).+)\s?(\S*)\Z/)
[matched[1].strip, matched[2].strip] if matched && matched.length >= 3
end
private
def context_contains_key?(context, key)
if context.respond_to?(:has_key?)
context.has_key?(key)
else
context.key?(key)
end
end
def gist_script_tag(gist_id, filename = nil)
url = "https://gist.github.com/#{gist_id}.js"
url = "#{url}?file=#{filename}" unless filename.to_s.empty?
""
end
def gist_noscript_tag(gist_id, filename = nil)
return if @settings && @settings["noscript"] == false
code = fetch_raw_code(gist_id, filename)
if !code.nil?
code = code.force_encoding(@encoding)
code = CGI.escapeHTML(code)
# CGI.escapeHTML behavior differs in Ruby < 2.0
# See https://github.com/jekyll/jekyll-gist/pull/28
code = code.gsub("'", "'") if RUBY_VERSION < "2.0"
""
else
Jekyll.logger.warn "Warning:", "The