1
+ ##
2
+ # Wrapper for the Pygments command line tool, pygmentize.
3
+ #
4
+ # Pygments: http://pygments.org/
5
+ #
6
+ # Assumes pygmentize is in the path. If not, set its location
7
+ # with Albino.bin = '/path/to/pygmentize'
8
+ #
9
+ # Use like so:
10
+ #
11
+ # @syntaxer = Albino.new('/some/file.rb', :ruby)
12
+ # puts @syntaxer.colorize
13
+ #
14
+ # This'll print out an HTMLized, Ruby-highlighted version
15
+ # of '/some/file.rb'.
16
+ #
17
+ # To use another formatter, pass it as the third argument:
18
+ #
19
+ # @syntaxer = Albino.new('/some/file.rb', :ruby, :bbcode)
20
+ # puts @syntaxer.colorize
21
+ #
22
+ # You can also use the #colorize class method:
23
+ #
24
+ # puts Albino.colorize('/some/file.rb', :ruby)
25
+ #
26
+ # Another also: you get a #to_s, for somewhat nicer use in Rails views.
27
+ #
28
+ # ... helper file ...
29
+ # def highlight(text)
30
+ # Albino.new(text, :ruby)
31
+ # end
32
+ #
33
+ # ... view file ...
34
+ # <%= highlight text %>
35
+ #
36
+ # The default lexer is 'text'. You need to specify a lexer yourself;
37
+ # because we are using STDIN there is no auto-detect.
38
+ #
39
+ # To see all lexers and formatters available, run `pygmentize -L`.
40
+ #
41
+ # Chris Wanstrath // [email protected]
42
+ # GitHub // http://github.com
43
+ #
44
+ require 'open4'
45
+
46
+ class Albino
47
+ @@bin = Rails . development? ? 'pygmentize' : '/usr/bin/pygmentize' rescue 'pygmentize'
48
+
49
+ def self . bin = ( path )
50
+ @@bin = path
51
+ end
52
+
53
+ def self . colorize ( *args )
54
+ new ( *args ) . colorize
55
+ end
56
+
57
+ def initialize ( target , lexer = :text , format = :html )
58
+ @target = File . exists? ( target ) ? File . read ( target ) : target rescue target
59
+ @options = { :l => lexer , :f => format , :O => 'encoding=utf-8' }
60
+ end
61
+
62
+ def execute ( command )
63
+ output = ''
64
+ Open4 . popen4 ( command ) do |pid , stdin , stdout , stderr |
65
+ stdin . puts @target
66
+ stdin . close
67
+ output = stdout . read . strip
68
+ [ stdout , stderr ] . each { |io | io . close }
69
+ end
70
+ output
71
+ end
72
+
73
+ def colorize ( options = { } )
74
+ html = execute ( @@bin + convert_options ( options ) )
75
+ # Work around an RDiscount bug: http://gist.github.com/97682
76
+ html . to_s . sub ( %r{</pre></div>\Z } , "</pre>\n </div>" )
77
+ end
78
+ alias_method :to_s , :colorize
79
+
80
+ def convert_options ( options = { } )
81
+ @options . merge ( options ) . inject ( '' ) do |string , ( flag , value ) |
82
+ string + " -#{ flag } #{ value } "
83
+ end
84
+ end
85
+ end
86
+
87
+ if $0 == __FILE__
88
+ require 'rubygems'
89
+ require 'test/spec'
90
+ require 'mocha'
91
+ begin require 'redgreen' ; rescue LoadError ; end
92
+
93
+ context "Albino" do
94
+ setup do
95
+ @syntaxer = Albino . new ( __FILE__ , :ruby )
96
+ end
97
+
98
+ specify "defaults to text" do
99
+ syntaxer = Albino . new ( __FILE__ )
100
+ syntaxer . expects ( :execute ) . with ( 'pygmentize -f html -l text' ) . returns ( true )
101
+ syntaxer . colorize
102
+ end
103
+
104
+ specify "accepts options" do
105
+ @syntaxer . expects ( :execute ) . with ( 'pygmentize -f html -l ruby' ) . returns ( true )
106
+ @syntaxer . colorize
107
+ end
108
+
109
+ specify "works with strings" do
110
+ syntaxer = Albino . new ( 'class New; end' , :ruby )
111
+ assert_match %r(highlight) , syntaxer . colorize
112
+ end
113
+
114
+ specify "aliases to_s" do
115
+ assert_equal @syntaxer . colorize , @syntaxer . to_s
116
+ end
117
+
118
+ specify "class method colorize" do
119
+ assert_equal @syntaxer . colorize , Albino . colorize ( __FILE__ , :ruby )
120
+ end
121
+ end
122
+ end
0 commit comments