jeffreyhunter77-R2Doc 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/CHANGELOG +1 -0
  2. data/LICENSE +20 -0
  3. data/Manifest +50 -0
  4. data/R2Doc.gemspec +33 -0
  5. data/README +103 -0
  6. data/README.rdoc +103 -0
  7. data/Rakefile +9 -0
  8. data/bin/r2doc +157 -0
  9. data/lib/r2doc.rb +7 -0
  10. data/lib/r2doc/context_extensions.rb +237 -0
  11. data/lib/r2doc/erb_template_engine.rb +11 -0
  12. data/lib/r2doc/generator.rb +123 -0
  13. data/lib/r2doc/rdoc_v2_generator.rb +112 -0
  14. data/lib/r2doc/template.rb +95 -0
  15. data/lib/r2doc/template/r2doc/_aliases.html.erb +22 -0
  16. data/lib/r2doc/template/r2doc/_attributes.html.erb +24 -0
  17. data/lib/r2doc/template/r2doc/_classes_and_modules.html.erb +13 -0
  18. data/lib/r2doc/template/r2doc/_constants.html.erb +22 -0
  19. data/lib/r2doc/template/r2doc/_method_detail.html.erb +10 -0
  20. data/lib/r2doc/template/r2doc/_method_details.html.erb +17 -0
  21. data/lib/r2doc/template/r2doc/_method_listing.html.erb +37 -0
  22. data/lib/r2doc/template/r2doc/_method_listing_row.html.erb +4 -0
  23. data/lib/r2doc/template/r2doc/_nav.html.erb +40 -0
  24. data/lib/r2doc/template/r2doc/_nav_item.html.erb +1 -0
  25. data/lib/r2doc/template/r2doc/class.html.erb +71 -0
  26. data/lib/r2doc/template/r2doc/file.html.erb +52 -0
  27. data/lib/r2doc/template/r2doc/images/blue-arrow-right.png +0 -0
  28. data/lib/r2doc/template/r2doc/images/blue-arrow-up.png +0 -0
  29. data/lib/r2doc/template/r2doc/images/blue-box.png +0 -0
  30. data/lib/r2doc/template/r2doc/images/blue-plus.png +0 -0
  31. data/lib/r2doc/template/r2doc/images/close-button.png +0 -0
  32. data/lib/r2doc/template/r2doc/images/green-arrow-right.png +0 -0
  33. data/lib/r2doc/template/r2doc/images/green-arrow-up.png +0 -0
  34. data/lib/r2doc/template/r2doc/images/nav-back.png +0 -0
  35. data/lib/r2doc/template/r2doc/images/nav-bottom.png +0 -0
  36. data/lib/r2doc/template/r2doc/images/nav-top.png +0 -0
  37. data/lib/r2doc/template/r2doc/images/orange-hash.png +0 -0
  38. data/lib/r2doc/template/r2doc/images/red-dash.png +0 -0
  39. data/lib/r2doc/template/r2doc/images/search-back.png +0 -0
  40. data/lib/r2doc/template/r2doc/images/top-back.png +0 -0
  41. data/lib/r2doc/template/r2doc/images/top-left.png +0 -0
  42. data/lib/r2doc/template/r2doc/images/top-right.png +0 -0
  43. data/lib/r2doc/template/r2doc/index.html.erb +42 -0
  44. data/lib/r2doc/template/r2doc/jquery.js +19 -0
  45. data/lib/r2doc/template/r2doc/prototype.js +285 -0
  46. data/lib/r2doc/template/r2doc/r2doc.css +400 -0
  47. data/lib/r2doc/template/r2doc/rdoc-utils.js +510 -0
  48. data/lib/r2doc/template/r2doc/rdoc.js.erb +164 -0
  49. data/lib/r2doc/template_util.rb +82 -0
  50. data/lib/rdoc/discover.rb +4 -0
  51. data/lib/rdoc/generators/r2doc_generator.rb +105 -0
  52. metadata +155 -0
@@ -0,0 +1,7 @@
1
+ # This file is intentionally blank.
2
+ #
3
+ # It exists as an easy mechanism to set up the document generator for use
4
+ # under RDoc v1.0.1 (e.g. +require 'r2doc'+). The only work that
5
+ # actually needs to be done is to include this directory in +$:+. That's
6
+ # done automatically by gem when this file is required. The remaining
7
+ # code is loaded by rdoc itself when it's run.
@@ -0,0 +1,237 @@
1
+ # Various extensions to the context classes made available to templates
2
+
3
+ module R2Doc
4
+
5
+ # Extensions for the RDoc::Generator::Context / Generators::ContextUser
6
+ # class
7
+ module ContextExtensions
8
+ # Numeric value associated with visibility values for sorting
9
+ VISIBILITY_VALUE = { :public=>0, :protected=>1, :private=>2 }
10
+
11
+ # Return the parent ContextUser of this object
12
+ def parent
13
+ p = (@context.parent.nil? || (@context == @context.parent)) ? nil : R2Doc.all_references[parent_name]
14
+ # guard against pollution of all_references with methods having conflicting names
15
+ (p.respond_to?(:is_method_context?) && p.is_method_context?) ? nil : p
16
+ end
17
+
18
+ # Return an array representing the navigational path to this class in
19
+ # the namespace hierarchy. The first item in the array is the
20
+ # outermost class or module. The class itself is not included in the
21
+ # array, nor is the root of the namespace. So, for a class
22
+ # A::B::C::D, the returned array will contain the A module, the B
23
+ # module, and the C module, in that order. All items in the array are
24
+ # instances of ContextUser
25
+ def name_path_to_parent
26
+ path = []
27
+ p = parent
28
+ while p do
29
+ path.unshift p
30
+ p = p.parent
31
+ end
32
+ path
33
+ end
34
+
35
+ # Return the description markup for this context
36
+ def description(temporaryPath = nil)
37
+ oldPath = self.path if (self.respond_to?(:path) && (!temporaryPath.nil?))
38
+ self.format_path = temporaryPath unless temporaryPath.nil?
39
+ d = markup(@context.comment)
40
+ self.format_path = oldPath if (self.respond_to?(:path) && (!temporaryPath.nil?))
41
+ d
42
+ end
43
+
44
+ # Return a list of Hashes for all constants containing the following keys:
45
+ # [<tt>:name</tt>] The constant name
46
+ # [<tt>:value</tt>] The value of the constant
47
+ # [<tt>:description</tt>] Constant description markup
48
+ def constants
49
+ @context.constants.sort{|a,b| a.name<=>b.name}.collect{|c| {:name=>c.name, :value=>c.value, :description=>markup(c.comment, true)}}
50
+ end
51
+
52
+ # Returns true if the context contains contants
53
+ def has_constants?
54
+ @context.constants.length > 0
55
+ end
56
+
57
+ # Return a list of Hashes for all aliases containing the following keys:
58
+ # [<tt>:old_name</tt>] The old name
59
+ # [<tt>:new_name</tt>] The new name
60
+ # [<tt>:description</tt>] Alias description markup
61
+ def aliases
62
+ @context.aliases.sort{|a,b| a.old_name<=>b.old_name}.collect{|al| {:old_name=>al.old_name, :new_name=>al.new_name, :description=>markup(al.comment, true)}}
63
+ end
64
+
65
+ # Return true if this context contains aliases
66
+ def has_aliases?
67
+ @context.aliases.length > 0
68
+ end
69
+
70
+ # Return a list of Hashes for all documentable attributes containing the following keys:
71
+ # [<tt>:name</tt>] The attribute name
72
+ # [<tt>:visibility</tt>] <tt>:public</tt>, <tt>:protected</tt>, or <tt>:private</tt>
73
+ # [<tt>:rw</tt>] <tt>'r'</tt> or <tt>'rw'</tt>
74
+ # [<tt>:description</tt>] Attribute description markup
75
+ def attributes
76
+ attrs = sort_members(@context.attributes).find_all{|a| @options.show_all || a.visibility == :public || a.visibility == :protected}
77
+ attrs.collect{|a| {:name=>a.name, :visibility=>a.visibility, :rw=>a.rw, :description=>markup(a.comment, true)}}
78
+ end
79
+
80
+ # Return true if this context contains attributes
81
+ def has_attributes?
82
+ a = @context.attributes.find{|a| @options.show_all || a.visibility == :public || a.visibility == :protected}
83
+ a ? true : false
84
+ end
85
+
86
+ # Returns a collection of HtmlMethod objects for all methods in this context
87
+ def all_methods
88
+ collect_methods unless @methods
89
+ @all_methods = sort_members(@methods) unless @all_methods
90
+ @all_methods
91
+ end
92
+
93
+ # Return a list of Hashes for all documentable class methods containing the following keys:
94
+ # [<tt>:name</tt>] The method name
95
+ # [<tt>:visibility</tt>] <tt>:public:</tt>, <tt>:protected</tt>, or <tt>:private</tt>
96
+ # [<tt>:params</tt>] Method call signature markup (does not include method name)
97
+ # [<tt>:callseq</tt>] Markup documenting alternative ways to call the method (should take precedence over name and params when present)
98
+ # [<tt>:url</tt>] The relative URL to the method from the documentation root (e.g. <tt>'classes/Foo.html#bar'</tt>)
99
+ # [<tt>:anchor</tt>] The name of the anchor for this method (e.g. <tt>'bar'</tt>)
100
+ # [<tt>:description</tt>] Method description markup
101
+ def class_methods
102
+ all_methods().find_all{|m| m.singleton && (@options.show_all || m.visibility == :public || m.visibility == :protected)}.collect{|m| method_hash(m)}
103
+ end
104
+
105
+ # Returns true if the context contains class (singleton) methods
106
+ def has_class_methods?
107
+ m = all_methods().find{|m| m.singleton && (@options.show_all || m.visibility == :public || m.visibility == :protected)}
108
+ m ? true : false
109
+ end
110
+
111
+ # Return a list of Hashes for all documentable instance methods. See class_methods for Hash key information.
112
+ def instance_methods
113
+ all_methods().find_all{|m| (!m.singleton) && (@options.show_all || m.visibility == :public || m.visibility == :protected)}.collect{|m| method_hash(m)}
114
+ end
115
+
116
+ # Returns true if the context contains instance (non-singleton) methods
117
+ def has_instance_methods?
118
+ m = all_methods().find{|m| (!m.singleton) && (@options.show_all || m.visibility == :public || m.visibility == :protected)}
119
+ m ? true : false
120
+ end
121
+
122
+ # The collection of modules contained within this context
123
+ def modules
124
+ return @modules if @modules
125
+ @modules = @context.modules.sort.find_all{|m| m.document_self}.collect{|m| R2Doc.all_references[m.full_name]}
126
+ end
127
+
128
+ # The collection of classes contained within this context
129
+ def classes
130
+ return @classes if @classes
131
+ @classes = @context.classes.sort.find_all{|c| c.document_self}.collect{|c| R2Doc.all_references[c.full_name]}
132
+ end
133
+
134
+ # Returns true if this context contains classes
135
+ def has_classes?
136
+ c = @context.classes.find{|c| c.document_self}
137
+ c ? true : false
138
+ end
139
+
140
+ # Returns true if this context contains modules
141
+ def has_modules?
142
+ m = @context.modules.find{|m| m.document_self}
143
+ m ? true : false
144
+ end
145
+
146
+ # Returns true if this context contains classes or modules
147
+ def has_classes_or_modules?
148
+ has_classes? || has_modules?
149
+ end
150
+
151
+ # Returns true if this context has included modules
152
+ def has_includes?
153
+ @context.includes.length > 0
154
+ end
155
+
156
+ # The collection of included modules. This returns a hash with the folliwing keys for each module:
157
+ # [<tt>:name</tt>] The module name
158
+ # [<tt>:url</tt>] The relative URL to the module from the documentation root
159
+ def includes
160
+ return @includes if @includes
161
+ @includes = []
162
+ @context.includes.each do |i|
163
+ ref = R2Doc.all_references[i.name]
164
+ ref = @context.find_symbol(i.name)
165
+ ref = ref.viewer if ref
166
+ if ref and ref.document_self
167
+ @includes << {:name=>i.name, :url=>ref.path}
168
+ else
169
+ @includes << {:name=>i.name}
170
+ end
171
+ end
172
+ @includes
173
+ end
174
+
175
+ # Returns true if this object is a method context
176
+ def is_method_context?
177
+ false
178
+ end
179
+
180
+ protected
181
+
182
+ # Sort members by visibility, then name
183
+ def sort_members(members)
184
+ members.sort do |a,b|
185
+ avis = VISIBILITY_VALUE[a.visibility]
186
+ bvis = VISIBILITY_VALUE[b.visibility]
187
+ (avis == bvis) ? a.name <=> b.name : avis <=> bvis
188
+ end
189
+ end
190
+
191
+ # Assembles a Hash for an HTMLMethod, +m+. This is used by class_methods and instance_methods.
192
+ def method_hash(m)
193
+ hash = {:name=>m.name, :visibility=>m.visibility, :params=>m.params, :url=>"#{path}\##{m.aref}", :anchor=>m.aref, :description=>m.description.strip}
194
+ hash[:callseq] = m.call_seq.gsub(/->/, '&rarr;') if m.call_seq
195
+ hash
196
+ end
197
+ end
198
+
199
+
200
+ # Extensions for the RDoc::Generator::Class / Generators::HtmlClass
201
+ # class
202
+ module ClassExtensions
203
+ # Return the HtmlClass for the super class, or the class name if undocumented
204
+ def superclass
205
+ lookup = (parent_name) ? "#{parent_name}::#{context_superclass}" : context_superclass
206
+ s = R2Doc.all_references[lookup] || R2Doc.all_references[context_superclass] || context_superclass
207
+ # in some cases conflicting method names can pollute AllReferences
208
+ s = s.name if (s.respond_to?(:is_method_context?) && s.is_method_context?)
209
+ s == self ? nil : s
210
+ end
211
+
212
+ # Return the shorter, unqualified name of the class
213
+ def short_name
214
+ @context.name
215
+ end
216
+
217
+ protected
218
+
219
+ # Returns nil instead of an error if superclass is called for a module
220
+ def context_superclass
221
+ @context.is_module? ? nil : @context.superclass
222
+ end
223
+
224
+ end
225
+
226
+
227
+
228
+ # Extensions for the RDoc::Generator::Method / Generators::HtmlMethod
229
+ # class
230
+ module MethodExtensions
231
+ # Returns true if this object is a method context
232
+ def is_method_context?
233
+ true
234
+ end
235
+ end
236
+
237
+ end
@@ -0,0 +1,11 @@
1
+ module R2Doc
2
+ # R2Doc engine for ERB templates
3
+ class ERBTemplateEngine
4
+ # Load a template
5
+ def self.load(filename)
6
+ ERB.new(File.open(filename) {|f| f.read})
7
+ end
8
+ end
9
+ end
10
+
11
+ R2Doc::TemplateManager.register_engine('erb', R2Doc::ERBTemplateEngine)
@@ -0,0 +1,123 @@
1
+ module R2Doc
2
+ # Custom generator
3
+ module Generator
4
+ # generate the docs
5
+ def generate(toplevels)
6
+ @toplevels = toplevels
7
+ @files = []
8
+ @classes = []
9
+ @hyperlinks = {}
10
+ @topmodules = []
11
+ @topclasses = []
12
+
13
+ generate_prep # hook for version-specific initalization
14
+
15
+ build_indices
16
+ generate_html
17
+ copy_static_files
18
+ end
19
+
20
+ protected
21
+
22
+ # load the template files
23
+ def load_html_template
24
+ ['class', 'file', 'rdoc'].each do |name|
25
+ R2Doc::TemplateManager.load_template("#{template_name}/#{name}")
26
+ end
27
+ end
28
+
29
+ # build indices of our objects
30
+ def build_indices
31
+ @toplevels.each do |toplevel|
32
+ @files << create_file_context(toplevel, @options)
33
+ end
34
+
35
+ get_toplevels.all_classes_and_modules.each do |cls|
36
+ build_class_list(cls, @files[0])
37
+ end
38
+
39
+ @classes.each do |c|
40
+ if c.parent.nil?
41
+ if c.context.is_module?
42
+ @topmodules << c
43
+ else
44
+ @topclasses << c
45
+ end
46
+ end
47
+ end
48
+ @topmodules.sort!
49
+ @topclasses.sort!
50
+ end
51
+
52
+ # Build a class list from a top-level class
53
+ def build_class_list(from, html_file)
54
+ @classes << create_class_context(from, html_file, @options)
55
+ from.each_classmodule do |mod|
56
+ build_class_list(mod, html_file)
57
+ end
58
+ end
59
+
60
+ # Outputs the html
61
+ def generate_html
62
+ @classes.each {|klass| render klass.path, :class, binding }
63
+ @files.each {|file| render file.path, :file, binding }
64
+ render 'rdoc.js', :rdoc
65
+ generate_index
66
+ end
67
+
68
+ # Generate an index file
69
+ def generate_index
70
+ # determine what to put in the index
71
+ ref = (@options.main_page && R2Doc.all_references[@options.main_page]) ?
72
+ R2Doc.all_references[@options.main_page] : nil
73
+ ref = ref.nil? ? @files.find{|f| f.document_self} : ref
74
+
75
+ # create the index
76
+ file = ref
77
+ render 'index.html', :index, binding
78
+ end
79
+
80
+ # Run a template and output the contents
81
+ def render(filename, template, b = nil)
82
+ @current_path = filename
83
+ File.makedirs(File.dirname(filename))
84
+ t = R2Doc::TemplateManager.load_template("#{template_name}/#{template.to_s}")
85
+ b = b.nil? ? binding : b
86
+
87
+ File.open(filename, 'w') {|f| f.write t.result(b)}
88
+ end
89
+
90
+
91
+ # build the static file list
92
+ def build_static_file_list
93
+ @static_files = {}
94
+ R2Doc::TemplateManager.template_directories.collect {|d|
95
+ "#{File.expand_path(d)}/#{template_name}"}.find_all{|d|
96
+ File.directory?(d)
97
+ }.each{|d| add_to_static_file_list d}
98
+ end
99
+
100
+ # recursively add a directory's contents to the static file list
101
+ def add_to_static_file_list(dir, relpath = '')
102
+ Dir.entries(File.join(dir, relpath)).each do |entry|
103
+ unless entry.match(/^\..?$/) || R2Doc::TemplateManager.is_registered_extension?(R2Doc::TemplateManager.file_extension(entry))
104
+ partial = relpath.empty? ? entry : File.join(relpath, entry)
105
+ full = File.join(dir, partial)
106
+ if File.directory?(full)
107
+ add_to_static_file_list dir, partial
108
+ else
109
+ @static_files[full] = partial
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ # copy any static files needed by the template
116
+ def copy_static_files
117
+ @static_files.each{|full,partial|
118
+ File.makedirs(File.dirname(partial))
119
+ File.copy(full, partial)
120
+ }
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,112 @@
1
+
2
+ require 'ftools'
3
+
4
+ require 'rdoc/rdoc'
5
+ require 'rdoc/generator/html'
6
+
7
+ require 'erb'
8
+
9
+ require 'r2doc/context_extensions'
10
+ require 'r2doc/template'
11
+ require 'r2doc/template_util'
12
+ require 'r2doc/generator'
13
+ require 'r2doc/erb_template_engine'
14
+
15
+ RDoc::Generator::Context.class_eval do
16
+ include R2Doc::ContextExtensions
17
+ end
18
+
19
+ RDoc::Generator::Class.class_eval do
20
+ include R2Doc::ClassExtensions
21
+ end
22
+
23
+ RDoc::Generator::Method.class_eval do
24
+ include R2Doc::MethodExtensions
25
+ end
26
+
27
+
28
+ module R2Doc
29
+ # Accessor for the AllReferences class
30
+ def self.all_references
31
+ RDoc::Generator::AllReferences
32
+ end
33
+ end
34
+
35
+ module RDoc
36
+
37
+ class ClassModule
38
+ # Retain support for old-style is_module? call
39
+ def is_module?
40
+ module?
41
+ end
42
+ end
43
+
44
+ module Generator
45
+
46
+ class Context #:nodoc:
47
+ protected
48
+ def format_path=(new_path)
49
+ @formatter = ::RDoc::Markup::ToHtmlCrossref.new(new_path, self, @options.show_hash)
50
+ end
51
+ end
52
+
53
+ class Method #:nodoc:
54
+ def create_source_code_file(code_body)
55
+ end
56
+ end
57
+
58
+ # R2Doc generator for RDoc v2
59
+ class R2DOC < HTML
60
+
61
+ RDoc.add_generator self
62
+
63
+ include ERB::Util
64
+ include R2Doc::TemplateUtil
65
+ include R2Doc::Generator
66
+
67
+ # Factory method
68
+ def R2DOC.for(options)
69
+ R2DOC.new(options)
70
+ end
71
+
72
+ # Constructor
73
+ def initialize(*args)
74
+ super
75
+ build_static_file_list
76
+ end
77
+
78
+ # Perform version-specific initialization
79
+ def generate_prep
80
+ @template_cache = Cache.instance
81
+ end
82
+
83
+ # Return the name of the template
84
+ def template_name
85
+ @options.template || 'r2doc'
86
+ end
87
+
88
+ # Return the list of top level objects for this RDoc version
89
+ def get_toplevels
90
+ TopLevel
91
+ end
92
+
93
+ # Create a new file object for this RDoc version
94
+ def create_file_context(context, options)
95
+ File.new(@template_cache, context, options, FILE_DIR)
96
+ end
97
+
98
+ # Create a new class object for this RDoc version
99
+ def create_class_context(context, file, options)
100
+ Class.new(@template_cache, context, file, CLASS_DIR, options)
101
+ end
102
+
103
+ # Return a list of all defined methods
104
+ def complete_method_list
105
+ Method.all_methods
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+
112
+ end