erlapi 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
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,353 @@
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 'rdoc/rdoc'
16
+ require 'rdoc/generator'
17
+ require 'rdoc/generator/markup'
18
+
19
+ require 'sdoc/github'
20
+ require 'sdoc/templatable'
21
+ require 'sdoc/helpers'
22
+
23
+ class RDoc::ClassModule
24
+ def document_self_or_methods
25
+ document_self || method_list.any?{ |m| m.document_self }
26
+ end
27
+
28
+ def with_documentation?
29
+ document_self_or_methods || classes_and_modules.any?{ |c| c.with_documentation? }
30
+ end
31
+ end
32
+
33
+ class Erlapi::Generator::SHtml
34
+ include ERB::Util
35
+ include Erlapi::Templatable
36
+ include Erlapi::Helpers
37
+
38
+ GENERATOR_DIRS = [File.join('erlapi', 'generator')]
39
+
40
+ # Used in js to reduce index sizes
41
+ TYPE_CLASS = 1
42
+ TYPE_METHOD = 2
43
+ TYPE_FILE = 3
44
+
45
+ TREE_FILE = File.join 'panel', 'tree.js'
46
+ SEARCH_INDEX_FILE = File.join 'panel', 'search_index.js'
47
+
48
+ FILE_DIR = 'files'
49
+ CLASS_DIR = 'classes'
50
+
51
+ RESOURCES_DIR = File.join('resources', '.')
52
+
53
+ attr_reader :basedir
54
+
55
+ def self.for(options)
56
+ self.new(options)
57
+ end
58
+
59
+ def self.template_dir template
60
+ $LOAD_PATH.map do |path|
61
+ GENERATOR_DIRS.map do |dir|
62
+ File.join path, dir, 'template', template
63
+ end
64
+ end.flatten.find do |dir|
65
+ File.directory? dir
66
+ end
67
+ end
68
+
69
+ def initialize(options)
70
+ @options = options
71
+ @options.diagram = false
72
+ @github_url_cache = {}
73
+
74
+ template = @options.template || 'direct'
75
+
76
+ templ_dir = self.class.template_dir template
77
+
78
+ raise "Could not find template #{template.inspect}" unless
79
+ templ_dir
80
+
81
+ @template_dir = Pathname.new File.expand_path(templ_dir)
82
+ @basedir = Pathname.pwd.expand_path
83
+ end
84
+
85
+ def generate( top_levels )
86
+ @outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir )
87
+ @files = top_levels.sort
88
+ @classes = RDoc::TopLevel.all_classes_and_modules.sort
89
+
90
+ # Now actually write the output
91
+ copy_resources
92
+ # generate_class_tree
93
+ generate_search_index
94
+ # generate_file_files
95
+ # generate_class_files
96
+ # generate_index_file
97
+ end
98
+
99
+ def class_dir
100
+ CLASS_DIR
101
+ end
102
+
103
+ def file_dir
104
+ FILE_DIR
105
+ end
106
+
107
+
108
+ protected
109
+ ### Output progress information if debugging is enabled
110
+ def debug_msg( *msg )
111
+ return unless $DEBUG_RDOC
112
+ $stderr.puts( *msg )
113
+ end
114
+
115
+ ### Create class tree structure and write it as json
116
+ def generate_class_tree
117
+ debug_msg "Generating class tree"
118
+ topclasses = @classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
119
+ tree = generate_file_tree + generate_class_tree_level(topclasses)
120
+ debug_msg " writing class tree to %s" % TREE_FILE
121
+ File.open(TREE_FILE, "w", 0644) do |f|
122
+ f.write('var tree = '); f.write(tree.to_json)
123
+ end unless $dryrun
124
+ end
125
+
126
+ ### Recursivly build class tree structure
127
+ def generate_class_tree_level(classes)
128
+ tree = []
129
+ classes.select{|c| c.with_documentation? }.sort.each do |klass|
130
+ item = [
131
+ klass.name,
132
+ klass.document_self_or_methods ? klass.path : '',
133
+ klass.module? ? '' : (klass.superclass ? " < #{String === klass.superclass ? klass.superclass : klass.superclass.full_name}" : ''),
134
+ generate_class_tree_level(klass.classes_and_modules)
135
+ ]
136
+ tree << item
137
+ end
138
+ tree
139
+ end
140
+
141
+ ### Create search index for all classes, methods and files
142
+ ### Wite it as json
143
+ def generate_search_index
144
+ debug_msg "Generating search index"
145
+
146
+ index = {
147
+ :searchIndex => [],
148
+ :longSearchIndex => [],
149
+ :info => []
150
+ }
151
+
152
+ add_class_search_index(index)
153
+ add_method_search_index(index)
154
+ add_file_search_index(index)
155
+
156
+ debug_msg " writing search index to %s" % SEARCH_INDEX_FILE
157
+ data = {
158
+ :index => index
159
+ }
160
+ File.open(SEARCH_INDEX_FILE, "w", 0644) do |f|
161
+ f.write('var search_data = '); f.write(data.to_json)
162
+ end unless $dryrun
163
+ end
164
+
165
+ ### Add files to search +index+ array
166
+ def add_file_search_index(index)
167
+ debug_msg " generating file search index"
168
+
169
+ @files.select { |file|
170
+ file.document_self
171
+ }.sort.each do |file|
172
+ index[:searchIndex].push( search_string(file.name) )
173
+ index[:longSearchIndex].push( search_string(file.path) )
174
+ index[:info].push([
175
+ file.name,
176
+ file.path,
177
+ file.path,
178
+ '',
179
+ snippet(file.comment),
180
+ TYPE_FILE
181
+ ])
182
+ end
183
+ end
184
+
185
+ ### Add classes to search +index+ array
186
+ def add_class_search_index(index)
187
+ debug_msg " generating class search index"
188
+
189
+ @classes.select { |klass|
190
+ klass.document_self_or_methods
191
+ }.sort.each do |klass|
192
+ index[:searchIndex].push( search_string(klass.name) )
193
+ index[:longSearchIndex].push( search_string(klass.parent.name) )
194
+ index[:info].push([
195
+ klass.name,
196
+ klass.parent.full_name,
197
+ klass.path,
198
+ klass.module? ? '' : (klass.superclass ? " < #{String === klass.superclass ? klass.superclass : klass.superclass.full_name}" : ''),
199
+ snippet(klass.comment),
200
+ TYPE_CLASS
201
+ ])
202
+ end
203
+ end
204
+
205
+ ### Add methods to search +index+ array
206
+ def add_method_search_index(index)
207
+ debug_msg " generating method search index"
208
+
209
+ list = @classes.map { |klass|
210
+ klass.method_list
211
+ }.flatten.sort{ |a, b| a.name == b.name ? a.parent.full_name <=> b.parent.full_name : a.name <=> b.name }.select { |method|
212
+ method.document_self
213
+ }
214
+ unless @options.show_all
215
+ list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }
216
+ end
217
+
218
+ list.each do |method|
219
+ index[:searchIndex].push( search_string(method.name) + '()' )
220
+ index[:longSearchIndex].push( search_string(method.parent.name) )
221
+ index[:info].push([
222
+ method.name,
223
+ method.parent.full_name,
224
+ method.path,
225
+ method.params,
226
+ snippet(method.comment),
227
+ TYPE_METHOD
228
+ ])
229
+ end
230
+ end
231
+
232
+ ### Generate a documentation file for each class
233
+ def generate_class_files
234
+ debug_msg "Generating class documentation in #@outputdir"
235
+ templatefile = @template_dir + 'class.rhtml'
236
+
237
+ @classes.each do |klass|
238
+ debug_msg " working on %s (%s)" % [ klass.full_name, klass.path ]
239
+ outfile = @outputdir + klass.path
240
+ rel_prefix = @outputdir.relative_path_from( outfile.dirname )
241
+
242
+ debug_msg " rendering #{outfile}"
243
+ self.render_template( templatefile, binding(), outfile )
244
+ end
245
+ end
246
+
247
+ ### Generate a documentation file for each file
248
+ def generate_file_files
249
+ debug_msg "Generating file documentation in #@outputdir"
250
+ templatefile = @template_dir + 'file.rhtml'
251
+
252
+ @files.each do |file|
253
+ outfile = @outputdir + file.path
254
+ debug_msg " working on %s (%s)" % [ file.full_name, outfile ]
255
+ rel_prefix = @outputdir.relative_path_from( outfile.dirname )
256
+
257
+ debug_msg " rendering #{outfile}"
258
+ self.render_template( templatefile, binding(), outfile )
259
+ end
260
+ end
261
+
262
+ def index_file
263
+ if @options.main_page && file = @files.find { |f| f.full_name == @options.main_page }
264
+ file
265
+ else
266
+ @files.first
267
+ end
268
+ end
269
+
270
+ ### Create index.html with frameset
271
+ def generate_index_file
272
+ debug_msg "Generating index file in #@outputdir"
273
+ templatefile = @template_dir + 'index.rhtml'
274
+ outfile = @outputdir + 'index.html'
275
+ index_path = index_file.path
276
+
277
+ self.render_template( templatefile, binding(), outfile )
278
+ end
279
+
280
+ ### Strip comments on a space after 100 chars
281
+ def snippet(str)
282
+ str ||= ''
283
+ if str =~ /^(?>\s*)[^\#]/
284
+ content = str
285
+ else
286
+ content = str.gsub(/^\s*(#+)\s*/, '')
287
+ end
288
+
289
+ content = content.sub(/^(.{100,}?)\s.*/m, "\\1").gsub(/\r?\n/m, ' ')
290
+
291
+ begin
292
+ content.to_json
293
+ rescue # might fail on non-unicode string
294
+ begin
295
+ content = Iconv.conv('latin1//ignore', "UTF8", content) # remove all non-unicode chars
296
+ content.to_json
297
+ rescue
298
+ content = '' # something hugely wrong happend
299
+ end
300
+ end
301
+ content
302
+ end
303
+
304
+ ### Build search index key
305
+ def search_string(string)
306
+ string ||= ''
307
+ string.downcase.gsub(/\s/,'')
308
+ end
309
+
310
+ ### Copy all the resource files to output dir
311
+ def copy_resources
312
+ resoureces_path = @template_dir + RESOURCES_DIR
313
+ debug_msg "Copying #{resoureces_path}/** to #{@outputdir}/**"
314
+ FileUtils.cp_r resoureces_path.to_s, @outputdir.to_s, :preserve => true unless $dryrun
315
+ end
316
+
317
+ class FilesTree
318
+ attr_reader :children
319
+ def add(path, url)
320
+ path = path.split(File::SEPARATOR) unless Array === path
321
+ @children ||= {}
322
+ if path.length == 1
323
+ @children[path.first] = url
324
+ else
325
+ @children[path.first] ||= FilesTree.new
326
+ @children[path.first].add(path[1, path.length], url)
327
+ end
328
+ end
329
+ end
330
+
331
+ def generate_file_tree
332
+ if @files.length > 1
333
+ @files_tree = FilesTree.new
334
+ @files.each do |file|
335
+ @files_tree.add(file.relative_name, file.path)
336
+ end
337
+ [['', '', 'files', generate_file_tree_level(@files_tree)]]
338
+ else
339
+ []
340
+ end
341
+ end
342
+
343
+ def generate_file_tree_level(tree)
344
+ tree.children.keys.sort.map do |name|
345
+ child = tree.children[name]
346
+ if String === child
347
+ [name, child, '', []]
348
+ else
349
+ ['', '', name, generate_file_tree_level(child)]
350
+ end
351
+ end
352
+ end
353
+ 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>