Chris@0
|
1 module CodeRay
|
Chris@0
|
2
|
Chris@0
|
3 # A little hack to enable CodeRay highlighting in RedCloth.
|
Chris@0
|
4 #
|
Chris@0
|
5 # Usage:
|
Chris@0
|
6 # require 'coderay'
|
Chris@0
|
7 # require 'coderay/for_redcloth'
|
Chris@0
|
8 # RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
|
Chris@0
|
9 #
|
Chris@0
|
10 # Make sure you have RedCloth 4.0.3 activated, for example by calling
|
Chris@0
|
11 # require 'rubygems'
|
Chris@0
|
12 # before RedCloth is loaded and before calling CodeRay.for_redcloth.
|
Chris@0
|
13 module ForRedCloth
|
Chris@0
|
14
|
Chris@0
|
15 def self.install
|
Chris@0
|
16 gem 'RedCloth', '>= 4.0.3' if defined? gem
|
Chris@0
|
17 require 'redcloth'
|
Chris@0
|
18 unless RedCloth::VERSION.to_s >= '4.0.3'
|
Chris@0
|
19 if defined? gem
|
Chris@0
|
20 raise 'CodeRay.for_redcloth needs RedCloth version 4.0.3 or later. ' +
|
Chris@0
|
21 "You have #{RedCloth::VERSION}. Please gem install RedCloth."
|
Chris@0
|
22 else
|
Chris@0
|
23 $".delete 'redcloth.rb' # sorry, but it works
|
Chris@0
|
24 require 'rubygems'
|
Chris@0
|
25 return install # retry
|
Chris@0
|
26 end
|
Chris@0
|
27 end
|
Chris@0
|
28 unless RedCloth::VERSION.to_s >= '4.2.2'
|
Chris@0
|
29 warn 'CodeRay.for_redcloth works best with RedCloth version 4.2.2 or later.'
|
Chris@0
|
30 end
|
Chris@0
|
31 RedCloth::TextileDoc.send :include, ForRedCloth::TextileDoc
|
Chris@0
|
32 RedCloth::Formatters::HTML.module_eval do
|
Chris@0
|
33 def unescape(html)
|
Chris@0
|
34 replacements = {
|
Chris@0
|
35 '&' => '&',
|
Chris@0
|
36 '"' => '"',
|
Chris@0
|
37 '>' => '>',
|
Chris@0
|
38 '<' => '<',
|
Chris@0
|
39 }
|
Chris@0
|
40 html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] }
|
Chris@0
|
41 end
|
Chris@0
|
42 undef code, bc_open, bc_close, escape_pre
|
Chris@0
|
43 def code(opts) # :nodoc:
|
Chris@0
|
44 opts[:block] = true
|
Chris@0
|
45 if !opts[:lang] && RedCloth::VERSION.to_s >= '4.2.0'
|
Chris@0
|
46 # simulating pre-4.2 behavior
|
Chris@0
|
47 if opts[:text].sub!(/\A\[(\w+)\]/, '')
|
Chris@0
|
48 if CodeRay::Scanners[$1].plugin_id == 'plaintext'
|
Chris@0
|
49 opts[:text] = $& + opts[:text]
|
Chris@0
|
50 else
|
Chris@0
|
51 opts[:lang] = $1
|
Chris@0
|
52 end
|
Chris@0
|
53 end
|
Chris@0
|
54 end
|
Chris@0
|
55 if opts[:lang] && !filter_coderay
|
Chris@0
|
56 require 'coderay'
|
Chris@0
|
57 @in_bc ||= nil
|
Chris@0
|
58 format = @in_bc ? :div : :span
|
Chris@0
|
59 opts[:text] = unescape(opts[:text]) unless @in_bc
|
Chris@0
|
60 highlighted_code = CodeRay.encode opts[:text], opts[:lang], format, :stream => true
|
Chris@0
|
61 highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) }
|
Chris@0
|
62 highlighted_code
|
Chris@0
|
63 else
|
Chris@0
|
64 "<code#{pba(opts)}>#{opts[:text]}</code>"
|
Chris@0
|
65 end
|
Chris@0
|
66 end
|
Chris@0
|
67 def bc_open(opts) # :nodoc:
|
Chris@0
|
68 opts[:block] = true
|
Chris@0
|
69 @in_bc = opts
|
Chris@0
|
70 opts[:lang] ? '' : "<pre#{pba(opts)}>"
|
Chris@0
|
71 end
|
Chris@0
|
72 def bc_close(opts) # :nodoc:
|
Chris@0
|
73 opts = @in_bc
|
Chris@0
|
74 @in_bc = nil
|
Chris@0
|
75 opts[:lang] ? '' : "</pre>\n"
|
Chris@0
|
76 end
|
Chris@0
|
77 def escape_pre(text)
|
Chris@0
|
78 if @in_bc ||= nil
|
Chris@0
|
79 text
|
Chris@0
|
80 else
|
Chris@0
|
81 html_esc(text, :html_escape_preformatted)
|
Chris@0
|
82 end
|
Chris@0
|
83 end
|
Chris@0
|
84 end
|
Chris@0
|
85 end
|
Chris@0
|
86
|
Chris@0
|
87 module TextileDoc # :nodoc:
|
Chris@0
|
88 attr_accessor :filter_coderay
|
Chris@0
|
89 end
|
Chris@0
|
90
|
Chris@0
|
91 end
|
Chris@0
|
92
|
Chris@0
|
93 end
|
Chris@0
|
94
|
Chris@0
|
95 CodeRay::ForRedCloth.install |