Upgraded Rails and RSpec
[monkeycharger.git] / vendor / plugins / rspec / doc / plugin / rspec_content.rb
blob1b3674192d0e8b57066beeba1109d1700ed7368d
1 require 'redcloth'
2 require 'syntax/convertors/html'
3 RUBY2HTML = Syntax::Convertors::HTML.for_syntax "ruby"
5 module RSpec
6   module SyntaxConverter 
7     # ruby/html content.  Initialize with the full
8     # <ruby>...</ruby> string                       
9     class RubyHtml < String     
10       def initialize(content)
11         @content = remove_ruby_tags(content)
12       end
13       
14       attr_reader :content
15       def to_s; @content.to_s; end
16       alias :inspect :to_s
17           
18       def to_html
19         '<pre class="ruby"><code>' + RUBY2HTML.convert(self.content.to_s, false) + '</code></pre>'
20       end
21       
22       def to_redcloth
23         "<notextile>" + self.to_html + "</notextile>"
24       end
25     
26     private     
27       def remove_ruby_tags(content_with_tags)
28         content_with_tags.gsub!(/<ruby>\s*/n, "")
29         content_with_tags.gsub!(/<\/ruby>/, "")
30       end  
31     end                   
33     # ruby/html content.  Initialize with
34     # <ruby file="..." /> or <ruby file="..."/>
35     class RubyHtmlFile < RubyHtml     
36       def initialize(content)                               
37         @content = find_file_contents(remove_ruby_tag(content))      
38       end 
39       
40     private      
41       def remove_ruby_tag(content_with_tag)      
42         content_with_tag.gsub(/<ruby\sfile\=\"(.*?)\"\s*\/>/, '\1')  
43       end                                                 
44         
45       def find_file_contents(filename)
46         begin
47           if !File.exists?(filename)
48             if filename[0...1] == "~"
49               filename = File.expand_path(filename)
50             else
51               # points to spec/doc/ with an absolute path
52               # notice the extra slash at the end.  This is there because 
53               # the docs, as they stand now assume the added slash
54               # the added / *probably* should come out later,
55               # depending on what David & Aslak think, since they are 
56               # the ones generating the docs
57               filename = File.expand_path(File.dirname(__FILE__) + "/../#{filename}")
58             end  
59           end    
60           File.read( filename )
61         rescue
62           raise "Given file <#{filename}> does not exist"
63         end                
64       end    
65     end
67   
68   
69     class RSpecContent < String
70       # Will parse the content for <ruby>...</ruby> html tags and
71        # <ruby file="..." />.  Note that all other content will 
72        # be assumed to be textile.   
73       def initialize(content)
74         @original_content = content
75         @content = parse_to_redcloth_content(content)    
76       end      
77       
78       attr_reader :original_content
79       attr_reader :content
80       alias :to_redcloth :content
81       
82       def to_html
83         redcloth_to_html(@content)
84       end
85       
86       alias :to_s :content 
87       alias :inspect :content
89     private   
90       #once you start some *real* html, can't provide redcloth or
91       # ruby tags inside an <tag>...</tag> entity.
92       # the content parser does not allow <ruby file='' />, only
93       # <ruby file="">.  please modify this at your will  
94       def parse_to_redcloth_content(content)
95         return "" if content.nil? || content.empty?
96         
97         pre_match, redcloth_content, post_match = match_content(content)  
98       
99         parse_to_redcloth_content(pre_match) +
100           redcloth_content +
101           parse_to_redcloth_content(post_match)
102       end 
103       
104       def match_content(content)
105         if real_content = content.match(/<ruby>(.|\n)*?<\/ruby>/) 
106           redcloth_content = RubyHtml.new(real_content[0]).to_redcloth        
107         elsif real_content = content.match(/<ruby file\=\".+?\"\s*\/>/)         
108           redcloth_content = RubyHtmlFile.new(real_content[0]).to_redcloth  
109         elsif invalid_content = content.match(/<ruby.*>/)
110           raise "Invalid Ruby HTML tag.  The Ruby Html tag must be declared in one of " +
111                 "the two following ways: \n" +
112                 "  1. <ruby>...inline_ruby...</ruby>\n" +
113                 "  2. <ruby filename=\"filename\" />\n" +
114                 "But it was declared as #{invalid_content[0]}\n"
115         else
116           return [nil, content, nil]
117         end                                                     
118         
119         return [real_content.pre_match, redcloth_content, real_content.post_match]
120       end                
121       
122       def redcloth_to_html(content)
123         return "" if content.nil? || content.empty?
124         begin
125           RedCloth.new( content ).to_html
126         rescue Exception => e
127           raise "Error converting Textile text to HTML: #{e.message}"   
128         end
129       end
130     end
131   end
132 end