source/_plugins/snippet.rb (137 lines of code) (raw):

require 'open-uri' require 'uri' require 'cgi' require 'digest' module Jekyll class Snippet < Liquid::Tag def initialize(tag_name, markup, tokens) parse_params(markup) unless @url.start_with?('http') @url = absolute_url(@url) end if @url =~ URI::regexp @content = fetchContent(@url) else STDERR.puts "Invalid URL passed to Snippet: " + @url end super end def render(context) if @content snippet = @content if @id snippet = snippet[/#{Regexp.escape("START SNIPPET: " + @id)}[^\n]*\n(.*?)\n[^\n]*#{Regexp.escape("END SNIPPET: " + @id)}/m, 1] unless snippet snippet = "START SNIPPET: " + @id + " not found in " + @url STDERR.puts snippet end end if @javadoc unless @javadoc.to_s.strip.casecmp("FALSE") == 0 snippet = snippet.gsub /^\s*\*/, '' snippet = CGI.unescapeHTML(snippet) end end if @lang snippet = "\r\n" + "```" + @lang + "\r\n" + snippet + "\r\n" + "```" + "\r\n" else snippet = "<p>" + escapeJekyll(snippet) + "</p>" end return snippet else raise 'Something went wrong in Snippet' end end def fetchContent(url) cacheKey = Digest::SHA1.hexdigest(url.strip) cacheFile = "target/snippet_" + cacheKey + ".cache" unless File.exist?(cacheFile) File.open(cacheFile, 'w') { |file| file.write(Net::HTTP.get(URI.parse(URI.encode(url.strip)))) } end file = File.open(cacheFile, "rb") content = file.read file.close return content end def parse_params(markup) markup_split = markup.split("|").reject { |s| s.empty? }.each { |param| parse_param(param) } end def parse_param(param) param_split = param.split("=", 2).reject { |s| s.empty? } if param_split[0].casecmp("id")==0 @id = param_split[1].strip else if param_split[0].casecmp("lang")==0 @lang = param_split[1].strip else if param_split[0].casecmp("javadoc")==0 @javadoc = param_split[1].strip else if param_split[0].casecmp("url")==0 @url = param_split[1].strip else @url = param.strip end end end end end def absolute_url(url) p = 'struts' f = '' tail = '' slashIndex = url.index('/') unless slashIndex url = url.strip.gsub!('.','/') tail = '.java' if url.start_with?('org/apache/struts2/dojo/') p = 'struts-archive' f = 'plugins/struts2-dojo-plugin/src/main/java/' else f = 'core/src/main/java/' end else baseUrl = url[0..slashIndex] url = url[slashIndex+1..-1] if baseUrl.casecmp("struts2-tags/") == 0 f = 'core/src/site/resources/tags/' else if url.start_with?('plugins/dojo/') p = 'struts-archive' f = 'plugins/struts2-dojo-plugin/' url = url[13..-1] end end end url = 'https://gitbox.apache.org/repos/asf?p=' + p + '.git;a=blob_plain;f=' + f + url + tail + ';hb=HEAD' end def escape_brackets(content) content.gsub(/{/,'&#x7b;').gsub(/}/, '&#x7d;') end def unescape_brackets(content) content.gsub!(/&(amp;)?#x7b;/, '{') content.gsub!(/&(amp;)?#x7d;/, '}') content end def escapeJekyll(content) # Escape markdown style code blocks # Escape four tab or space indented code blocks content = content.gsub /^((\t| {4})[^\n].+?)\n($|\S)/m do "#{escape_brackets $1}\n#{$3}" end # Escape in-line code backticks content = content.gsub /(`[^`\n]+?`)/ do "#{escape_brackets $1}" end # Escape in-line code double backticks content = content.gsub /(``[^\n]+?``)/ do escape_brackets $1 end # Escape highlight and codeblock tag contents content = content.gsub /^({%\s*(codeblock|highlight).+?%})(.+?){%\s*end(codeblock|highlight)\s*%}/m do "#{$1}{% raw %}#{unescape_brackets $3}{% endraw %}{% end#{$4} %}" end # Escape codefenced codeblocks content = content.gsub /^(`{3}.+?`{3})/m do # Replace any raw/endraw tags inside of codefence block # as some of the regex above may have escaped contents # of the codefence block # code = unescape_brackets($1).gsub(/{% (end)?raw %}/, '') # Wrap codefence content in raw tags "{% raw %}\n#{code}\n{% endraw %}" end content end end end Liquid::Template.register_tag('snippet', Jekyll::Snippet)