erlapi 0.1.9

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 (100) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +15 -0
  5. data/Rakefile +56 -0
  6. data/VERSION +1 -0
  7. data/bin/erlapi +26 -0
  8. data/erlapi.gemspec +140 -0
  9. data/lib/erlapi.rb +38 -0
  10. data/lib/erlapi/generator.rb +194 -0
  11. data/lib/erlapi/generator/shtml.rb +353 -0
  12. data/lib/erlapi/generator/template/direct/_context.rhtml +172 -0
  13. data/lib/erlapi/generator/template/direct/class.rhtml +40 -0
  14. data/lib/erlapi/generator/template/direct/file.rhtml +30 -0
  15. data/lib/erlapi/generator/template/direct/index.rhtml +14 -0
  16. data/lib/erlapi/generator/template/direct/resources/apple-touch-icon.png +0 -0
  17. data/lib/erlapi/generator/template/direct/resources/css/main.css +263 -0
  18. data/lib/erlapi/generator/template/direct/resources/css/panel.css +383 -0
  19. data/lib/erlapi/generator/template/direct/resources/css/reset.css +53 -0
  20. data/lib/erlapi/generator/template/direct/resources/favicon.ico +0 -0
  21. data/lib/erlapi/generator/template/direct/resources/i/arrows.png +0 -0
  22. data/lib/erlapi/generator/template/direct/resources/i/results_bg.png +0 -0
  23. data/lib/erlapi/generator/template/direct/resources/i/tree_bg.png +0 -0
  24. data/lib/erlapi/generator/template/direct/resources/js/jquery-1.3.2.min.js +19 -0
  25. data/lib/erlapi/generator/template/direct/resources/js/jquery-effect.js +593 -0
  26. data/lib/erlapi/generator/template/direct/resources/js/main.js +22 -0
  27. data/lib/erlapi/generator/template/direct/resources/js/searchdoc.js +628 -0
  28. data/lib/erlapi/generator/template/direct/resources/panel/index.html +71 -0
  29. data/lib/erlapi/generator/template/merge/index.rhtml +14 -0
  30. data/lib/erlapi/generator/template/shtml/_context.rhtml +164 -0
  31. data/lib/erlapi/generator/template/shtml/class.rhtml +46 -0
  32. data/lib/erlapi/generator/template/shtml/file.rhtml +37 -0
  33. data/lib/erlapi/generator/template/shtml/index.rhtml +14 -0
  34. data/lib/erlapi/generator/template/shtml/resources/apple-touch-icon.png +0 -0
  35. data/lib/erlapi/generator/template/shtml/resources/css/main.css +191 -0
  36. data/lib/erlapi/generator/template/shtml/resources/css/panel.css +383 -0
  37. data/lib/erlapi/generator/template/shtml/resources/css/reset.css +53 -0
  38. data/lib/erlapi/generator/template/shtml/resources/favicon.ico +0 -0
  39. data/lib/erlapi/generator/template/shtml/resources/i/arrows.png +0 -0
  40. data/lib/erlapi/generator/template/shtml/resources/i/results_bg.png +0 -0
  41. data/lib/erlapi/generator/template/shtml/resources/i/tree_bg.png +0 -0
  42. data/lib/erlapi/generator/template/shtml/resources/js/jquery-1.3.2.min.js +19 -0
  43. data/lib/erlapi/generator/template/shtml/resources/js/main.js +34 -0
  44. data/lib/erlapi/generator/template/shtml/resources/js/searchdoc.js +628 -0
  45. data/lib/erlapi/generator/template/shtml/resources/panel/index.html +71 -0
  46. data/lib/erlapi/helpers.rb +26 -0
  47. data/lib/erlapi/merge.rb +217 -0
  48. data/lib/erlapi/parser.rb +134 -0
  49. data/lib/erlapi/shtml.rb +351 -0
  50. data/lib/erlapi/templatable.rb +51 -0
  51. data/lib/erlapi/templates/html/direct/_context.rhtml +172 -0
  52. data/lib/erlapi/templates/html/direct/class.rhtml +40 -0
  53. data/lib/erlapi/templates/html/direct/file.rhtml +30 -0
  54. data/lib/erlapi/templates/html/direct/index.rhtml +14 -0
  55. data/lib/erlapi/templates/html/direct/resources/apple-touch-icon.png +0 -0
  56. data/lib/erlapi/templates/html/direct/resources/css/main.css +263 -0
  57. data/lib/erlapi/templates/html/direct/resources/css/panel.css +383 -0
  58. data/lib/erlapi/templates/html/direct/resources/css/reset.css +53 -0
  59. data/lib/erlapi/templates/html/direct/resources/favicon.ico +0 -0
  60. data/lib/erlapi/templates/html/direct/resources/i/arrows.png +0 -0
  61. data/lib/erlapi/templates/html/direct/resources/i/results_bg.png +0 -0
  62. data/lib/erlapi/templates/html/direct/resources/i/tree_bg.png +0 -0
  63. data/lib/erlapi/templates/html/direct/resources/js/jquery-1.3.2.min.js +19 -0
  64. data/lib/erlapi/templates/html/direct/resources/js/jquery-effect.js +593 -0
  65. data/lib/erlapi/templates/html/direct/resources/js/main.js +22 -0
  66. data/lib/erlapi/templates/html/direct/resources/js/searchdoc.js +628 -0
  67. data/lib/erlapi/templates/html/direct/resources/panel/index.html +71 -0
  68. data/lib/erlapi/templates/html/merge/index.rhtml +14 -0
  69. data/lib/erlapi/templates/html/shtml/_context.rhtml +68 -0
  70. data/lib/erlapi/templates/html/shtml/class.rhtml +25 -0
  71. data/lib/erlapi/templates/html/shtml/file.rhtml +37 -0
  72. data/lib/erlapi/templates/html/shtml/index.rhtml +14 -0
  73. data/lib/erlapi/templates/html/shtml/resources copy/apple-touch-icon.png +0 -0
  74. data/lib/erlapi/templates/html/shtml/resources copy/css/main.css +195 -0
  75. data/lib/erlapi/templates/html/shtml/resources copy/css/panel.css +383 -0
  76. data/lib/erlapi/templates/html/shtml/resources copy/css/reset.css +53 -0
  77. data/lib/erlapi/templates/html/shtml/resources copy/favicon.ico +0 -0
  78. data/lib/erlapi/templates/html/shtml/resources copy/i/arrows.png +0 -0
  79. data/lib/erlapi/templates/html/shtml/resources copy/i/results_bg.png +0 -0
  80. data/lib/erlapi/templates/html/shtml/resources copy/i/tree_bg.png +0 -0
  81. data/lib/erlapi/templates/html/shtml/resources copy/js/jquery-1.3.2.min.js +19 -0
  82. data/lib/erlapi/templates/html/shtml/resources copy/js/main.js +34 -0
  83. data/lib/erlapi/templates/html/shtml/resources copy/js/searchdoc.js +628 -0
  84. data/lib/erlapi/templates/html/shtml/resources copy/panel/index.html +71 -0
  85. data/lib/erlapi/templates/html/shtml/resources/apple-touch-icon.png +0 -0
  86. data/lib/erlapi/templates/html/shtml/resources/css/main.css +263 -0
  87. data/lib/erlapi/templates/html/shtml/resources/css/panel.css +383 -0
  88. data/lib/erlapi/templates/html/shtml/resources/css/reset.css +53 -0
  89. data/lib/erlapi/templates/html/shtml/resources/favicon.ico +0 -0
  90. data/lib/erlapi/templates/html/shtml/resources/i/arrows.png +0 -0
  91. data/lib/erlapi/templates/html/shtml/resources/i/results_bg.png +0 -0
  92. data/lib/erlapi/templates/html/shtml/resources/i/tree_bg.png +0 -0
  93. data/lib/erlapi/templates/html/shtml/resources/js/jquery-1.3.2.min.js +19 -0
  94. data/lib/erlapi/templates/html/shtml/resources/js/jquery-effect.js +593 -0
  95. data/lib/erlapi/templates/html/shtml/resources/js/main.js +22 -0
  96. data/lib/erlapi/templates/html/shtml/resources/js/searchdoc.js +620 -0
  97. data/lib/erlapi/templates/html/shtml/resources/panel/index.html +71 -0
  98. data/test/erlapi_test.rb +7 -0
  99. data/test/test_helper.rb +10 -0
  100. metadata +155 -0
@@ -0,0 +1,351 @@
1
+ require 'rubygems'
2
+ gem "rdoc", ">= 2.4.2"
3
+ if Gem.available? "json"
4
+ gem "json", ">= 1.1.3"
5
+ else
6
+ gem "json_pure", ">= 1.1.3"
7
+ end
8
+
9
+ require 'iconv'
10
+ require 'json'
11
+ require 'pathname'
12
+ require 'fileutils'
13
+ require 'erb'
14
+
15
+ require 'sdoc/github'
16
+ require 'sdoc/templatable'
17
+ require 'sdoc/helpers'
18
+
19
+ class RDoc::ClassModule
20
+ def document_self_or_methods
21
+ document_self || method_list.any?{ |m| m.document_self }
22
+ end
23
+
24
+ def with_documentation?
25
+ document_self_or_methods || classes_and_modules.any?{ |c| c.with_documentation? }
26
+ end
27
+ end
28
+
29
+ class RDoc::Generator::SHtml
30
+ RDoc::RDoc.add_generator( self )
31
+ include ERB::Util
32
+ include SDoc::GitHub
33
+ include SDoc::Templatable
34
+ include SDoc::Helpers
35
+
36
+ GENERATOR_DIRS = [File.join('sdoc', 'generator'), File.join('rdoc', 'generator')]
37
+
38
+ # Used in js to reduce index sizes
39
+ TYPE_CLASS = 1
40
+ TYPE_METHOD = 2
41
+ TYPE_FILE = 3
42
+
43
+ TREE_FILE = File.join 'panel', 'tree.js'
44
+ SEARCH_INDEX_FILE = File.join 'panel', 'search_index.js'
45
+
46
+ FILE_DIR = 'files'
47
+ CLASS_DIR = 'classes'
48
+
49
+ RESOURCES_DIR = File.join('resources', '.')
50
+
51
+ attr_reader :basedir
52
+
53
+ def self.for(options)
54
+ self.new(options)
55
+ end
56
+
57
+ def self.template_dir template
58
+ $LOAD_PATH.map do |path|
59
+ GENERATOR_DIRS.map do |dir|
60
+ File.join path, dir, 'template', template
61
+ end
62
+ end.flatten.find do |dir|
63
+ File.directory? dir
64
+ end
65
+ end
66
+
67
+ def initialize(options)
68
+ @options = options
69
+ @options.diagram = false
70
+ @github_url_cache = {}
71
+
72
+ template = @options.template || 'direct'
73
+
74
+ templ_dir = self.class.template_dir template
75
+
76
+ raise RDoc::Error, "could not find template #{template.inspect}" unless
77
+ templ_dir
78
+
79
+ @template_dir = Pathname.new File.expand_path(templ_dir)
80
+ @basedir = Pathname.pwd.expand_path
81
+ end
82
+
83
+ def generate( top_levels )
84
+ @outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir )
85
+ @files = top_levels.sort
86
+ @classes = RDoc::TopLevel.all_classes_and_modules.sort
87
+
88
+ # Now actually write the output
89
+ copy_resources
90
+ generate_class_tree
91
+ generate_search_index
92
+ generate_file_files
93
+ generate_class_files
94
+ generate_index_file
95
+ end
96
+
97
+ def class_dir
98
+ CLASS_DIR
99
+ end
100
+
101
+ def file_dir
102
+ FILE_DIR
103
+ end
104
+
105
+
106
+ protected
107
+ ### Output progress information if debugging is enabled
108
+ def debug_msg( *msg )
109
+ return unless $DEBUG_RDOC
110
+ $stderr.puts( *msg )
111
+ end
112
+
113
+ ### Create class tree structure and write it as json
114
+ def generate_class_tree
115
+ debug_msg "Generating class tree"
116
+ topclasses = @classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
117
+ tree = generate_file_tree + generate_class_tree_level(topclasses)
118
+ debug_msg " writing class tree to %s" % TREE_FILE
119
+ File.open(TREE_FILE, "w", 0644) do |f|
120
+ f.write('var tree = '); f.write(tree.to_json)
121
+ end unless $dryrun
122
+ end
123
+
124
+ ### Recursivly build class tree structure
125
+ def generate_class_tree_level(classes)
126
+ tree = []
127
+ classes.select{|c| c.with_documentation? }.sort.each do |klass|
128
+ item = [
129
+ klass.name,
130
+ klass.document_self_or_methods ? klass.path : '',
131
+ klass.module? ? '' : (klass.superclass ? " < #{String === klass.superclass ? klass.superclass : klass.superclass.full_name}" : ''),
132
+ generate_class_tree_level(klass.classes_and_modules)
133
+ ]
134
+ tree << item
135
+ end
136
+ tree
137
+ end
138
+
139
+ ### Create search index for all classes, methods and files
140
+ ### Wite it as json
141
+ def generate_search_index
142
+ debug_msg "Generating search index"
143
+
144
+ index = {
145
+ :searchIndex => [],
146
+ :longSearchIndex => [],
147
+ :info => []
148
+ }
149
+
150
+ add_class_search_index(index)
151
+ add_method_search_index(index)
152
+ add_file_search_index(index)
153
+
154
+ debug_msg " writing search index to %s" % SEARCH_INDEX_FILE
155
+ data = {
156
+ :index => index
157
+ }
158
+ File.open(SEARCH_INDEX_FILE, "w", 0644) do |f|
159
+ f.write('var search_data = '); f.write(data.to_json)
160
+ end unless $dryrun
161
+ end
162
+
163
+ ### Add files to search +index+ array
164
+ def add_file_search_index(index)
165
+ debug_msg " generating file search index"
166
+
167
+ @files.select { |file|
168
+ file.document_self
169
+ }.sort.each do |file|
170
+ index[:searchIndex].push( search_string(file.name) )
171
+ index[:longSearchIndex].push( search_string(file.path) )
172
+ index[:info].push([
173
+ file.name,
174
+ file.path,
175
+ file.path,
176
+ '',
177
+ snippet(file.comment),
178
+ TYPE_FILE
179
+ ])
180
+ end
181
+ end
182
+
183
+ ### Add classes to search +index+ array
184
+ def add_class_search_index(index)
185
+ debug_msg " generating class search index"
186
+
187
+ @classes.select { |klass|
188
+ klass.document_self_or_methods
189
+ }.sort.each do |klass|
190
+ index[:searchIndex].push( search_string(klass.name) )
191
+ index[:longSearchIndex].push( search_string(klass.parent.name) )
192
+ index[:info].push([
193
+ klass.name,
194
+ klass.parent.full_name,
195
+ klass.path,
196
+ klass.module? ? '' : (klass.superclass ? " < #{String === klass.superclass ? klass.superclass : klass.superclass.full_name}" : ''),
197
+ snippet(klass.comment),
198
+ TYPE_CLASS
199
+ ])
200
+ end
201
+ end
202
+
203
+ ### Add methods to search +index+ array
204
+ def add_method_search_index(index)
205
+ debug_msg " generating method search index"
206
+
207
+ list = @classes.map { |klass|
208
+ klass.method_list
209
+ }.flatten.sort{ |a, b| a.name == b.name ? a.parent.full_name <=> b.parent.full_name : a.name <=> b.name }.select { |method|
210
+ method.document_self
211
+ }
212
+ unless @options.show_all
213
+ list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }
214
+ end
215
+
216
+ list.each do |method|
217
+ index[:searchIndex].push( search_string(method.name) + '()' )
218
+ index[:longSearchIndex].push( search_string(method.parent.name) )
219
+ index[:info].push([
220
+ method.name,
221
+ method.parent.full_name,
222
+ method.path,
223
+ method.params,
224
+ snippet(method.comment),
225
+ TYPE_METHOD
226
+ ])
227
+ end
228
+ end
229
+
230
+ ### Generate a documentation file for each class
231
+ def generate_class_files
232
+ debug_msg "Generating class documentation in #@outputdir"
233
+ templatefile = @template_dir + 'class.rhtml'
234
+
235
+ @classes.each do |klass|
236
+ debug_msg " working on %s (%s)" % [ klass.full_name, klass.path ]
237
+ outfile = @outputdir + klass.path
238
+ rel_prefix = @outputdir.relative_path_from( outfile.dirname )
239
+
240
+ debug_msg " rendering #{outfile}"
241
+ self.render_template( templatefile, binding(), outfile )
242
+ end
243
+ end
244
+
245
+ ### Generate a documentation file for each file
246
+ def generate_file_files
247
+ debug_msg "Generating file documentation in #@outputdir"
248
+ templatefile = @template_dir + 'file.rhtml'
249
+
250
+ @files.each do |file|
251
+ outfile = @outputdir + file.path
252
+ debug_msg " working on %s (%s)" % [ file.full_name, outfile ]
253
+ rel_prefix = @outputdir.relative_path_from( outfile.dirname )
254
+
255
+ debug_msg " rendering #{outfile}"
256
+ self.render_template( templatefile, binding(), outfile )
257
+ end
258
+ end
259
+
260
+ def index_file
261
+ if @options.main_page && file = @files.find { |f| f.full_name == @options.main_page }
262
+ file
263
+ else
264
+ @files.first
265
+ end
266
+ end
267
+
268
+ ### Create index.html with frameset
269
+ def generate_index_file
270
+ debug_msg "Generating index file in #@outputdir"
271
+ templatefile = @template_dir + 'index.rhtml'
272
+ outfile = @outputdir + 'index.html'
273
+ index_path = index_file.path
274
+
275
+ self.render_template( templatefile, binding(), outfile )
276
+ end
277
+
278
+ ### Strip comments on a space after 100 chars
279
+ def snippet(str)
280
+ str ||= ''
281
+ if str =~ /^(?>\s*)[^\#]/
282
+ content = str
283
+ else
284
+ content = str.gsub(/^\s*(#+)\s*/, '')
285
+ end
286
+
287
+ content = content.sub(/^(.{100,}?)\s.*/m, "\\1").gsub(/\r?\n/m, ' ')
288
+
289
+ begin
290
+ content.to_json
291
+ rescue # might fail on non-unicode string
292
+ begin
293
+ content = Iconv.conv('latin1//ignore', "UTF8", content) # remove all non-unicode chars
294
+ content.to_json
295
+ rescue
296
+ content = '' # something hugely wrong happend
297
+ end
298
+ end
299
+ content
300
+ end
301
+
302
+ ### Build search index key
303
+ def search_string(string)
304
+ string ||= ''
305
+ string.downcase.gsub(/\s/,'')
306
+ end
307
+
308
+ ### Copy all the resource files to output dir
309
+ def copy_resources
310
+ resoureces_path = @template_dir + RESOURCES_DIR
311
+ debug_msg "Copying #{resoureces_path}/** to #{@outputdir}/**"
312
+ FileUtils.cp_r resoureces_path.to_s, @outputdir.to_s, :preserve => true unless $dryrun
313
+ end
314
+
315
+ class FilesTree
316
+ attr_reader :children
317
+ def add(path, url)
318
+ path = path.split(File::SEPARATOR) unless Array === path
319
+ @children ||= {}
320
+ if path.length == 1
321
+ @children[path.first] = url
322
+ else
323
+ @children[path.first] ||= FilesTree.new
324
+ @children[path.first].add(path[1, path.length], url)
325
+ end
326
+ end
327
+ end
328
+
329
+ def generate_file_tree
330
+ if @files.length > 1
331
+ @files_tree = FilesTree.new
332
+ @files.each do |file|
333
+ @files_tree.add(file.relative_name, file.path)
334
+ end
335
+ [['', '', 'files', generate_file_tree_level(@files_tree)]]
336
+ else
337
+ []
338
+ end
339
+ end
340
+
341
+ def generate_file_tree_level(tree)
342
+ tree.children.keys.sort.map do |name|
343
+ child = tree.children[name]
344
+ if String === child
345
+ [name, child, '', []]
346
+ else
347
+ ['', '', name, generate_file_tree_level(child)]
348
+ end
349
+ end
350
+ end
351
+ end
@@ -0,0 +1,51 @@
1
+ module Erlapi::Templatable
2
+ ### Load and render the erb template in the given +templatefile+ within the
3
+ ### specified +context+ (a Binding object) and return output
4
+ ### Both +templatefile+ and +outfile+ should be Pathname-like objects.
5
+ def eval_template(templatefile, context)
6
+ template_src = templatefile.read
7
+ template = ERB.new( template_src, nil, '<>' )
8
+ template.filename = templatefile.to_s
9
+
10
+ begin
11
+ template.result( context )
12
+ rescue NoMethodError => err
13
+ raise StandardError, "Error while evaluating %s: %s (at %p)" % [
14
+ templatefile.to_s,
15
+ err.message,
16
+ eval( "_erbout[-50,50]", context )
17
+ ], err.backtrace
18
+ end
19
+ end
20
+
21
+ ### Load and render the erb template with the given +template_name+ within
22
+ ### current context. Adds all +local_assigns+ to context
23
+ def include_template(template_name, local_assigns = {})
24
+ source = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
25
+ eval("#{source};templatefile = Erlapi::Generator::TEMPLATE_DIR + template_name;eval_template(templatefile, binding)")
26
+ end
27
+
28
+ ### Load and render the erb template in the given +templatefile+ within the
29
+ ### specified +context+ (a Binding object) and write it out to +outfile+.
30
+ ### Both +templatefile+ and +outfile+ should be Pathname-like objects.
31
+ def render_template( templatefile, context, outfile )
32
+ output = eval_template(templatefile, context)
33
+
34
+ # TODO delete this dirty hack when documentation for example for GeneratorMethods will not be cutted off by <script> tag
35
+ begin
36
+ if output.respond_to? :force_encoding
37
+ encoding = output.encoding
38
+ output = output.force_encoding('ASCII-8BIT').gsub('<script>', '&lt;script;&gt;').force_encoding(encoding)
39
+ else
40
+ output = output.gsub('<script>', '&lt;script&gt;')
41
+ end
42
+ rescue Exception => e
43
+
44
+ end
45
+
46
+ outfile.dirname.mkpath
47
+ outfile.open( 'w', 0644 ) do |file|
48
+ file.print( output )
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,172 @@
1
+ <div id="content">
2
+ <% unless (desc = context.description).empty? %>
3
+ <div class="description">
4
+ <%= desc %>
5
+ </div>
6
+ <% end %>
7
+
8
+ <% unless context.requires.empty? %>
9
+ <div class="sectiontitle">Required Files</div>
10
+ <ul>
11
+ <% context.requires.each do |req| %>
12
+ <li><%= h req.name %></li>
13
+ <% end %>
14
+ </ul>
15
+ <% end %>
16
+
17
+ <% sections = context.sections.select { |section| section.title } %>
18
+ <% unless sections.empty? %>
19
+ <div class="sectiontitle">Contents</div>
20
+ <ul>
21
+ <% sections.each do |section| %>
22
+ <li><a href="#<%= section.sequence %>"><%= h section.title %></a></li>
23
+ <% end %>
24
+ </ul>
25
+ <% end %>
26
+
27
+ <%
28
+ list = context.method_list
29
+ unless @options.show_all
30
+ list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }
31
+ end
32
+ %>
33
+ <% unless list.empty? %>
34
+ <div class="sectiontitle">Methods</div>
35
+ <dl class="methods">
36
+ <% each_letter_group(list) do |group| %>
37
+ <dt><%= group[:name] %></dt>
38
+ <dd>
39
+ <ul>
40
+ <% group[:methods].each_with_index do |method, i| %>
41
+ <li><a href="#<%= method.aref %>"><%= method.name %></a><%= ',' unless group[:methods].size == i+1 %></li>
42
+ <% end %>
43
+ </ul>
44
+ </dd>
45
+ <% end %>
46
+ </dl>
47
+ <% end %>
48
+
49
+ <% unless context.includes.empty? %>
50
+ <div class="sectiontitle">Included Modules</div>
51
+ <ul>
52
+ <% context.includes.each do |inc| %>
53
+ <li>
54
+ <% unless String === inc.module %>
55
+ <a href="<%= context.aref_to inc.module.path %>"><%= h inc.module.full_name %></a>
56
+ <% else %>
57
+ <span><%= h inc.name %></span>
58
+ <% end %>
59
+ START:includes
60
+ </li>
61
+ <% end %>
62
+ </ul>
63
+ <% end %>
64
+
65
+ <% sections.each do |section| %>
66
+ <div class="sectiontitle"><a name="<%= h section.sequence %>"><%= h section.title %></a></div>
67
+ <% unless (description = section.description).empty? %>
68
+ <div class="description">
69
+ <%= description %>
70
+ </div>
71
+ <% end %>
72
+ <% end %>
73
+
74
+ <% unless context.classes_and_modules.empty? %>
75
+ <div class="sectiontitle">Classes and Modules</div>
76
+ <ul>
77
+ <% (context.modules.sort + context.classes.sort).each do |mod| %>
78
+ <li><span class="type"><%= mod.type.upcase %></span> <a href="<%= context.aref_to mod.path %>"><%= mod.full_name %></a></li>
79
+ <% end %>
80
+ </ul>
81
+ <% end %>
82
+
83
+ <% unless context.constants.empty? %>
84
+ <div class="sectiontitle">Constants</div>
85
+ <table border='0' cellpadding='5'>
86
+ <% context.each_constant do |const| %>
87
+ <tr valign='top'>
88
+ <td class="attr-name"><%= h const.name %></td>
89
+ <td>=</td>
90
+ <td class="attr-value"><%= h const.value %></td>
91
+ </tr>
92
+ <% unless (description = const.description).empty? %>
93
+ <tr valign='top'>
94
+ <td>&nbsp;</td>
95
+ <td colspan="2" class="attr-desc"><%= description %></td>
96
+ </tr>
97
+ <% end %>
98
+ <% end %>
99
+ </table>
100
+ <% end %>
101
+
102
+ <% unless context.attributes.empty? %>
103
+ <div class="sectiontitle">Attributes</div>
104
+ <table border='0' cellpadding='5'>
105
+ <% context.each_attribute do |attrib| %>
106
+ <tr valign='top'>
107
+ <td class='attr-rw'>
108
+ [<%= attrib.rw %>]
109
+ </td>
110
+ <td class='attr-name'><%= h attrib.name %></td>
111
+ <td class='attr-desc'><%= attrib.description.strip %></td>
112
+ </tr>
113
+ <% end %>
114
+ </table>
115
+ <% end %>
116
+
117
+ <% context.methods_by_type.each do |type, visibilities|
118
+ next if visibilities.empty?
119
+ visibilities.each do |visibility, methods|
120
+ next if methods.empty?
121
+ next unless @options.show_all || visibility == :public || visibility == :protected || methods.any? {|m| m.force_documentation }
122
+ %>
123
+ <div class="sectiontitle"><%= type.capitalize %> <%= visibility.to_s.capitalize %> methods</div>
124
+ <% methods.each do |method| %>
125
+ <div class="method">
126
+ <div class="title" id="<%= method.aref %>">
127
+ <% if method.call_seq %>
128
+ <a name="<%= method.aref %>"></a><b><%= method.call_seq.gsub(/->/, '&rarr;') %></b>
129
+ <% else %>
130
+ <a name="<%= method.aref %>"></a><b><%= h method.name %></b><%= h method.params %>
131
+ <% end %>
132
+ </div>
133
+ <% unless (description = method.description).empty? %>
134
+ <div class="description">
135
+ <%= description %>
136
+ </div>
137
+ <% end %>
138
+ <% unless method.aliases.empty? %>
139
+ <div class="aka">
140
+ This method is also aliased as
141
+ <% method.aliases.each do |aka| %>
142
+ <a href="<%= context.aref_to aka.path %>"><%= h aka.name %></a>
143
+ <% end %>
144
+ </div>
145
+ <% end %>
146
+ <% if method.token_stream %>
147
+ <% markup = method.markup_code %>
148
+ <div class="sourcecode">
149
+ <p class="source-link">
150
+ Source: <a href="javascript:toggleSource('<%= method.aref %>_source')" id="l_<%= method.aref %>_source">show</a>
151
+ <%
152
+ if markup =~ /File\s(\S+), line (\d+)/
153
+ path = $1
154
+ line = $2.to_i
155
+ end
156
+ github = github_url(path)
157
+ if github
158
+ %>
159
+ | <a href="<%= "#{github}#L#{line}" %>" target="_blank" class="github_url">on GitHub</a>
160
+ <% end %>
161
+ </p>
162
+ <div id="<%= method.aref %>_source" class="dyn-source">
163
+ <pre><%= method.markup_code %></pre>
164
+ </div>
165
+ </div>
166
+ <% end %>
167
+ </div>
168
+ <% end
169
+ end
170
+ end
171
+ %>
172
+ </div>