diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb index fe260c2..055aebe 100644 --- a/plugins/backtick_code_block.rb +++ b/plugins/backtick_code_block.rb @@ -5,35 +5,28 @@ module BacktickCodeBlock AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+)\s*(.+)?/i LangCaption = /([^\s]+)\s*(.+)?/i def render_code_block(input) - @options = nil - @caption = nil - @lang = nil - @url = nil - @title = nil input.encode!("UTF-8") - input.gsub(/^`{3} *([^\n]+)?\n([\S\s]+?)\n`{3}/m) do - @options = $1 || '' - str = $2 - - if @options =~ AllOptions - @lang = $1 - @caption = "
#{$2}#{$4 || 'link'}
" - elsif @options =~ LangCaption - @lang = $1 - @caption = "
#{$2}
" - end - - if @lang.nil? || @lang == 'plain' - code = tableize_code(str.gsub('<','<').gsub('>','>')) - "
#{@caption}#{code}
" - else - if @lang.include? "-raw" - raw = "``` #{@options.sub('-raw', '')}\n" - raw += str - raw += "\n```\n" + input.gsub /^`{3}(.+?)`{3}/m do + str = $1.to_s + linenos = true + start = 1 + str.gsub /([^\n]+)?\n(.+?)\Z/m do + @options = $1 || '' + code = $2.to_s + if @options =~ /\s*linenos:false/i + linenos = false + @options = @options.sub(/\s*linenos:false/i,'') + end + if @options =~ /\s*start:(\d+)/i + start = $1.to_i + @options = @options.sub(/\s*start:\d+/i,'') + end + if @options =~ AllOptions + highlight(code, $1, {caption: $2, url: $3, anchor: $4 || 'Link', linenos: linenos, start: start}) + elsif @options =~ LangCaption + highlight(code, $1, {caption: $2 || '', linenos: linenos, start: start}) else - code = highlight(str, @lang) - "
#{@caption}#{code}
" + highlight(code, 'plain', {linenos: linenos, start: start}) end end end diff --git a/plugins/code_block.rb b/plugins/code_block.rb index 28cc841..a396d06 100644 --- a/plugins/code_block.rb +++ b/plugins/code_block.rb @@ -48,48 +48,44 @@ module Jekyll class CodeBlock < Liquid::Block include HighlightCode - include TemplateWrapper CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i Caption = /(\S[\S\s]*)/ def initialize(tag_name, markup, tokens) - @title = nil @caption = nil - @filetype = nil - @highlight = true + @url = nil + @lang = nil + @start = 1 if markup =~ /\s*lang:(\w+)/i - @filetype = $1 + @lang = $1 markup = markup.sub(/lang:\w+/i,'') end - if markup =~ CaptionUrlTitle - @file = $1 - @caption = "
#{$1}#{$4}
" - elsif markup =~ CaptionUrl - @file = $1 - @caption = "
#{$1}link
" - elsif markup =~ Caption - @file = $1 - @caption = "
#{$1}
\n" + if markup =~ /\s*start:(\d+)/i + @start = $1.to_i + markup = markup.sub(/\s*start:\d+/i,'') end - if @file =~ /\S[\S\s]*\w+\.(\w+)/ && @filetype.nil? - @filetype = $1 + if markup =~ CaptionUrlTitle + @caption = $1 + @url = $2 + $3 + @anchor = $4 + elsif markup =~ CaptionUrl + @caption = $1 + @url = $2 + $3 + elsif markup =~ Caption + @caption = $1 + end + if @caption =~ /\S[\S\s]*\w+\.(\w+)/ && @lang.nil? + @lang = $1 end super end def render(context) - code = super - source = "
" - source += @caption if @caption - if @filetype - source += " #{highlight(code, @filetype)}
" - else - source += "#{tableize_code(code.lstrip.rstrip.gsub(/" - end - source = safe_wrap(source) - source = context['pygments_prefix'] + source if context['pygments_prefix'] - source = source + context['pygments_suffix'] if context['pygments_suffix'] - source + code = super.strip + code = highlight(code, @lang, {caption: @caption, url: @url, anchor: @anchor, start: @start}) + code = context['pygments_prefix'] + code if context['pygments_prefix'] + code = code + context['pygments_suffix'] if context['pygments_suffix'] + code end end end diff --git a/plugins/include_code.rb b/plugins/include_code.rb index fc6daa3..93ad728 100644 --- a/plugins/include_code.rb +++ b/plugins/include_code.rb @@ -21,21 +21,34 @@ # require './plugins/pygments_code' -require './plugins/raw' require 'pathname' module Jekyll class IncludeCodeTag < Liquid::Tag include HighlightCode - include TemplateWrapper def initialize(tag_name, markup, tokens) @title = nil @file = nil + @start = 1 + @end = nil if markup.strip =~ /\s*lang:(\w+)/i @filetype = $1 markup = markup.strip.sub(/lang:\w+/i,'') end + if markup =~ /\s*start:(\d+)/i + @start = $1.to_i + markup = markup.sub(/\s*start:\d+/i,'') + end + if markup =~ /\s*end:(\d+)/i + @end = $1.to_i + markup = markup.sub(/\s*end:\d+/i,'') + end + if markup =~ /\s*range:(\d+),(\d+)/i + @start = $1.to_i + @end = $2.to_i + markup = markup.sub(/\s*range:\d+,\d+/i,'') + end if markup.strip =~ /(.*)?(\s+|^)(\/*\S+)/i @title = $1 || nil @file = $3 @@ -58,12 +71,17 @@ module Jekyll Dir.chdir(code_path) do code = file.read + length = code.lines.count + @end ||= length + return "#{file} is #{length} lines long, cannot begin at line #{@start}" if @start > length + return "#{file} is #{length} lines long, cannot read beyond line #{@end}" if @end > length + if @start > 1 or @end < length + code = code.split(/\n/).slice(@start -1, @end + 1 - @start).join("\n") + end @filetype = file.extname.sub('.','') if @filetype.nil? title = @title ? "#{@title} (#{file.basename})" : file.basename url = "/#{code_dir}/#{@file}" - source = "
#{title} download
\n" - source += " #{highlight(code, @filetype)}
" - safe_wrap(source) + highlight(code, @filetype, {caption: title, url: url, anchor: 'download', start: @start}) end end end diff --git a/plugins/octopress_filters.rb b/plugins/octopress_filters.rb index abadf9d..4faf84f 100644 --- a/plugins/octopress_filters.rb +++ b/plugins/octopress_filters.rb @@ -9,10 +9,10 @@ module OctopressFilters include BacktickCodeBlock include TemplateWrapper def pre_filter(input) - input = render_code_block(input) input.gsub /(.+?<\/figure>)/m do safe_wrap($1) end + input = render_code_block(input) end def post_filter(input) input = unwrap(input) diff --git a/plugins/pygments_code.rb b/plugins/pygments_code.rb index 3c486db..9c548b7 100644 --- a/plugins/pygments_code.rb +++ b/plugins/pygments_code.rb @@ -1,3 +1,5 @@ +#require 'albino' +require './plugins/raw' require 'pygments' require 'fileutils' require 'digest/md5' @@ -6,33 +8,77 @@ PYGMENTS_CACHE_DIR = File.expand_path('../../.pygments-cache', __FILE__) FileUtils.mkdir_p(PYGMENTS_CACHE_DIR) module HighlightCode - def highlight(str, lang) - lang = 'ruby' if lang == 'ru' - lang = 'objc' if lang == 'm' - lang = 'perl' if lang == 'pl' - lang = 'yaml' if lang == 'yml' - str = pygments(str, lang).match(/
(.+)<\/pre>/m)[1].to_s.gsub(/ *$/, '') #strip out divs 
- tableize_code(str, lang) - end - + include TemplateWrapper def pygments(code, lang) path = File.join(PYGMENTS_CACHE_DIR, "#{lang}-#{Digest::MD5.hexdigest(code)}.html") if defined?(PYGMENTS_CACHE_DIR) if File.exist?(path) highlighted_code = File.read(path) else - highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html', :options => {:encoding => 'utf-8'}) + #highlighted_code = Albino.new(code, lang, :html) + highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html', :options => {:encoding => 'utf-8'}) File.open(path, 'w') {|f| f.print(highlighted_code) } if path end - highlighted_code + highlighted_code.to_s + rescue + puts $!,$@ end - def tableize_code (str, lang = '') - table = '
'
-    code = ''
-    str.lines.each_with_index do |line,index|
-      table += "#{index+1}\n"
-      code  += "#{line}"
+  def highlight(code, lang, options = {})
+    lang = 'ruby' if lang == 'ru'
+    lang = 'objc' if lang == 'm'
+    lang = 'perl' if lang == 'pl'
+    lang = 'yaml' if lang == 'yml'
+    lang = 'coffeescript' if lang == 'coffee'
+    lang = 'plain' if lang == '' or lang.nil?
+
+    caption = options[:caption]    || nil
+    url     = options[:url]        || nil
+    anchor  = options[:anchor]     || nil
+    wrap    = options[:wrap]       || true
+    linenos = options[:linenos]
+    start   = options[:start]
+
+    if lang == 'plain'
+      # Escape html tags
+      code = code.gsub('<','<').gsub('>','>')
+    elsif lang.include? "-raw"
+      output  = "``` #{$1.sub('-raw', '')}\n"
+      output += code
+      output += "\n```\n"
+    else
+      code = pygments(code, lang).match(/
(.+)<\/pre>/m)[1].gsub(/ *$/, '') #strip out divs 
end - table += "
#{code}
" + + code = tableize_code(code, lang, { linenos: linenos, start: start }) + caption = captionize(caption, url, anchor) if caption + + figure = "
#{caption}#{code}
" + figure = safe_wrap(figure) if wrap + figure + end + + def captionize (caption, url, anchor) + figcaption = "
#{caption}" + figcaption += " #{anchor || 'link'}" if url + figcaption += "
" + end + + def tableize_code (code, lang, options = {}) + start = options[:start] + lines = options[:linenos] || true + table = "
" + table += number_lines(start, code.lines.count) if lines + table += "
"
+    table += code.gsub /^((.+)?(\n?))/, '\1'
+    table +="
" + end + + def number_lines (start, count) + start ||= 1 + lines = "
"
+    count.times do |index|
+      lines += "#{index + start}\n"
+    end
+    lines += "
" end end