Permalink
Browse files

use pygments for code highlighting if --pygments is specified

  • Loading branch information...
1 parent 1e13d2f commit f00272ea527f73bcc868b6de92d00d0e43fb86ef @mojombo mojombo committed Dec 13, 2008
Showing with 147 additions and 3 deletions.
  1. +2 −0 History.txt
  2. +4 −0 bin/jekyll
  3. +7 −0 lib/jekyll.rb
  4. +116 −0 lib/jekyll/albino.rb
  5. +18 −3 lib/jekyll/blocks.rb
View
2 History.txt
@@ -1,4 +1,6 @@
==
+ * Major Features
+ * Code highlighting with Pygments if --pygments is specified
* Minor Enhancements
* Output informative message if RDiscount is not available [github.com/JackDanger]
* Bug Fixes
View
4 bin/jekyll
@@ -24,6 +24,10 @@ opts = OptionParser.new do |opts|
opts.on("--auto", "Auto-regenerate") do
options[:auto] = true
end
+
+ opts.on("--pygments", "Use pygments to highlight code") do
+ Jekyll.pygments = true
+ end
end
opts.parse!
View
7 lib/jekyll.rb
@@ -28,10 +28,17 @@
require 'jekyll/post'
require 'jekyll/filters'
require 'jekyll/blocks'
+require 'jekyll/albino'
module Jekyll
VERSION = '0.1.4'
+ class << self
+ attr_accessor :pygments
+ end
+
+ Jekyll.pygments = false
+
def self.process(source, dest)
Jekyll::Site.new(source, dest).process
end
View
116 lib/jekyll/albino.rb
@@ -0,0 +1,116 @@
+##
+# Wrapper for the Pygments command line tool, pygmentize.
+#
+# Pygments: http://pygments.org/
+#
+# Assumes pygmentize is in the path. If not, set its location
+# with Albino.bin = '/path/to/pygmentize'
+#
+# Use like so:
+#
+# @syntaxer = Albino.new('/some/file.rb', :ruby)
+# puts @syntaxer.colorize
+#
+# This'll print out an HTMLized, Ruby-highlighted version
+# of '/some/file.rb'.
+#
+# To use another formatter, pass it as the third argument:
+#
+# @syntaxer = Albino.new('/some/file.rb', :ruby, :bbcode)
+# puts @syntaxer.colorize
+#
+# You can also use the #colorize class method:
+#
+# puts Albino.colorize('/some/file.rb', :ruby)
+#
+# Another also: you get a #to_s, for somewhat nicer use in Rails views.
+#
+# ... helper file ...
+# def highlight(text)
+# Albino.new(text, :ruby)
+# end
+#
+# ... view file ...
+# <%= highlight text %>
+#
+# The default lexer is 'text'. You need to specify a lexer yourself;
+# because we are using STDIN there is no auto-detect.
+#
+# To see all lexers and formatters available, run `pygmentize -L`.
+#
+# Chris Wanstrath // chris@ozmm.org
+# GitHub // http://github.com
+#
+require 'open4'
+
+class Albino
+ @@bin = Rails.development? ? 'pygmentize' : '/usr/bin/pygmentize' rescue 'pygmentize'
+
+ def self.bin=(path)
+ @@bin = path
+ end
+
+ def self.colorize(*args)
+ new(*args).colorize
+ end
+
+ def initialize(target, lexer = :text, format = :html)
+ @target = File.exists?(target) ? File.read(target) : target rescue target
+ @options = { :l => lexer, :f => format }
+ end
+
+ def execute(command)
+ pid, stdin, stdout, stderr = Open4.popen4(command)
+ stdin.puts @target
+ stdin.close
+ stdout.read.strip
+ end
+
+ def colorize(options = {})
+ execute @@bin + convert_options(options)
+ end
+ alias_method :to_s, :colorize
+
+ def convert_options(options = {})
+ @options.merge(options).inject('') do |string, (flag, value)|
+ string + " -#{flag} #{value}"
+ end
+ end
+end
+
+if $0 == __FILE__
+ require 'rubygems'
+ require 'test/spec'
+ require 'mocha'
+ begin require 'redgreen'; rescue LoadError; end
+
+ context "Albino" do
+ setup do
+ @syntaxer = Albino.new(__FILE__, :ruby)
+ end
+
+ specify "defaults to text" do
+ syntaxer = Albino.new(__FILE__)
+ syntaxer.expects(:execute).with('pygmentize -f html -l text').returns(true)
+ syntaxer.colorize
+ end
+
+ specify "accepts options" do
+ @syntaxer.expects(:execute).with('pygmentize -f html -l ruby').returns(true)
+ @syntaxer.colorize
+ end
+
+ specify "works with strings" do
+ syntaxer = Albino.new('class New; end', :ruby)
+ assert_match %r(highlight), syntaxer.colorize
+ end
+
+ specify "aliases to_s" do
+ assert_equal @syntaxer.colorize, @syntaxer.to_s
+ end
+
+ specify "class method colorize" do
+ assert_equal @syntaxer.colorize, Albino.colorize(__FILE__, :ruby)
+ end
+ end
+end
View
21 lib/jekyll/blocks.rb
@@ -1,4 +1,5 @@
module Jekyll
+
class Highlight < Liquid::Block
include Liquid::StandardFilters
@@ -8,15 +9,29 @@ def initialize(tag_name, lang, tokens)
end
def render(context)
- #The div is required because RDiscount blows ass
+ if Jekyll.pygments
+ render_pygments(context, super.to_s)
+ else
+ render_codehighlighter(context, super.to_s)
+ end
+ end
+
+ def render_pygments(context, code)
+ "<notextile>" + Albino.new(code, @lang).to_s + "</notextile>"
+ end
+
+ def render_codehighlighter(context, code)
+ #The div is required because RDiscount blows ass
<<-HTML
<div>
<pre>
- <code class='#{@lang}'>#{h(super.to_s).strip}</code>
+ <code class='#{@lang}'>#{h(code).strip}</code>
</pre>
</div>
HTML
- end
+ end
end
+
end
+
Liquid::Template.register_tag('highlight', Jekyll::Highlight)

1 comment on commit f00272e

@JackDanger

Fantastic! I was looking for javascript-only libraries in case syntax highlighting would have complicated Jekyll. Looks like you found a great way to put this together.

Please sign in to comment.