shomen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ module Shomen
2
+
3
+ module Model
4
+ require 'shomen/model/module'
5
+
6
+ #
7
+ class Class < Module
8
+
9
+ #
10
+ def self.type; 'class'; end
11
+
12
+ #
13
+ attr_accessor :superclass
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,34 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/abstract'
6
+
7
+ #
8
+ class Constant < Abstract
9
+ #
10
+ def self.type; 'constant'; end
11
+
12
+ # Constant's basename, must start with a capitalized letter.
13
+ attr_accessor :name
14
+
15
+ #
16
+ attr_accessor :namespace
17
+
18
+ #
19
+ attr_accessor :comment
20
+
21
+ # Format of comment (rdoc, markdown or plain).
22
+ attr_accessor :format
23
+
24
+ #
25
+ attr_accessor :value
26
+
27
+ #
28
+ attr_accessor :files
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,36 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/abstract'
6
+
7
+ #
8
+ class Document < Abstract
9
+ #
10
+ def self.type
11
+ 'document'
12
+ end
13
+
14
+ #def key=(path)
15
+ # path = '/' + path unless path[0,1] == '/'
16
+ # super(path)
17
+ #end
18
+
19
+ attr_accessor :name
20
+
21
+ #attr_accessor :parent
22
+
23
+ attr_accessor :path
24
+
25
+ attr_accessor :mtime
26
+
27
+ attr_accessor :text
28
+
29
+ # Format of comment (rdoc, markdown or plain).
30
+ attr_accessor :format
31
+
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,35 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/abstract'
6
+
7
+ #
8
+ class Interface < AbstractPrime
9
+
10
+ # TODO: validate that there is an interface image.
11
+ def initialize(settings={})
12
+ #@table = {'arguments'=>[], 'parameters'=>[]}
13
+ super(settings)
14
+ end
15
+
16
+ # The source code "image" of the method's inteface.
17
+ attr_accessor :signature
18
+
19
+ # Arguments breakdown.
20
+ attr_accessor :arguments
21
+
22
+ # Parameters breakdown.
23
+ attr_accessor :parameters
24
+
25
+ # Block
26
+ attr_accessor :block
27
+
28
+ # Return value.
29
+ attr_accessor :returns
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,104 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/abstract'
6
+ require 'shomen/model/interface'
7
+
8
+ #
9
+ class Method < Abstract
10
+
11
+ #
12
+ def initialize(settings={})
13
+ super(settings)
14
+ @table['declarations'] ||= []
15
+ end
16
+
17
+ # Method's name.
18
+ attr_accessor :name
19
+
20
+ # Method's namespace.
21
+ attr_accessor :namespace
22
+
23
+ # Comment accompanying method definition.
24
+ attr_accessor :comment
25
+
26
+ # Format of comment (rdoc, markdown or plain).
27
+ attr_accessor :format
28
+
29
+ # Singleton method `true` or `false/nil`.
30
+ attr_accessor :singleton
31
+
32
+ # Delarations is a list of keywords that designates characteristics
33
+ # about a method. Common characteristics include `reader`, `writer`
34
+ # or `accessor` if the method is defined via an attr method; `public`
35
+ # `private` or `protected` given the methods visibility; and `class`
36
+ # or `instance` given the methods scope. Default designations are
37
+ # are impled if not specifically stated, such as `public` and `instance`.
38
+ #
39
+ # Using a declarations list simplifies the Shomen data format by allowing
40
+ # declarations to be freely defined, rather than creating a field for each
41
+ # possible designation possible.
42
+ attr_accessor :declarations
43
+
44
+ # Aliases.
45
+ attr_accessor :aliases
46
+
47
+ # Aliases.
48
+ attr_accessor :alias_for
49
+
50
+ # Breakdown of interfaces signature, arguments, parameters, block argument
51
+ # an return values.
52
+ attr_accessor :interfaces
53
+
54
+ #
55
+ def interfaces=(array)
56
+ self['interfaces'] = (
57
+ array.map do |settings|
58
+ case settings
59
+ when Interface
60
+ settings
61
+ else
62
+ Interface.new(settings)
63
+ end
64
+ end
65
+ )
66
+ end
67
+
68
+ # List of possible returns types.
69
+ attr_accessor :returns
70
+
71
+ # List of possible raised errors.
72
+ attr_accessor :raises
73
+
74
+ # Method generated dynamically?
75
+ attr_accessor :dynamic
76
+
77
+ # Filename.
78
+ attr_accessor :file
79
+
80
+ # Line number.
81
+ attr_accessor :line
82
+
83
+ # Source code.
84
+ attr_accessor :source
85
+
86
+ # Source code language.
87
+ attr_accessor :language
88
+
89
+
90
+ # Deprecated method.
91
+ alias :parent :namespace
92
+
93
+ #
94
+ def to_h
95
+ h = super
96
+ h['!'] = 'method'
97
+ h['interfaces'] = (interfaces || []).map{ |s| s.to_h }
98
+ h
99
+ end
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,56 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/abstract'
6
+
7
+ #
8
+ class Module < Abstract
9
+
10
+ #
11
+ def self.type; 'module'; end
12
+
13
+ # Method's name.
14
+ attr_accessor :name
15
+
16
+ # Namespace of module is the path of the class or module
17
+ # containing this module.
18
+ attr_accessor :namespace
19
+
20
+ # Comment associated with module.
21
+ attr_accessor :comment
22
+
23
+ # Format of comment (rdoc, markdown or plain).
24
+ attr_accessor :format
25
+
26
+ # Mixins.
27
+ attr_accessor :includes
28
+
29
+ # Metaclass mixins.
30
+ attr_accessor :extensions
31
+
32
+ # Constants defined within this module.
33
+ attr_accessor :constants
34
+
35
+ #
36
+ attr_accessor :modules
37
+
38
+ #
39
+ attr_accessor :classes
40
+
41
+ # List of instance methods defined in the module.
42
+ attr_accessor :methods
43
+
44
+ # List of attributes.
45
+ attr_accessor :accessors
46
+
47
+ # The files in which the module is defined.
48
+ attr_accessor :files
49
+
50
+ #
51
+ alias :fullname :path
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,49 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/document'
6
+
7
+ #
8
+ class Script < Document
9
+ #
10
+ def self.type; 'script'; end
11
+
12
+ #
13
+ attr_accessor :source
14
+
15
+ # Route textto source.
16
+ alias :text :source
17
+ alias :text= :source=
18
+
19
+ #
20
+ attr_accessor :language
21
+
22
+ #
23
+ attr_accessor :name
24
+
25
+ attr_accessor :path
26
+
27
+ attr_accessor :mtime
28
+
29
+ attr_accessor :header
30
+
31
+ attr_accessor :footer
32
+
33
+ attr_accessor :requires
34
+
35
+ attr_accessor :constants
36
+
37
+ attr_accessor :modules
38
+
39
+ attr_accessor :classes
40
+
41
+ attr_accessor :class_methods
42
+
43
+ attr_accessor :methods
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,598 @@
1
+ #begin
2
+ # # requiroing rubygems is needed here b/c ruby comes with
3
+ # # rdoc but it's not the latest version.
4
+ # require 'rubygems'
5
+ # #gem 'rdoc', '>= 2.4' unless ENV['RDOC_TEST'] or defined?($rdoc_rakefile)
6
+ # gem "rdoc", ">= 2.4.2"
7
+ #rescue
8
+ #end
9
+
10
+ require 'fileutils'
11
+ require 'pathname'
12
+ require 'yaml'
13
+ require 'json'
14
+
15
+ require 'rdoc/rdoc'
16
+ require 'rdoc/generator'
17
+ require 'rdoc/generator/markup'
18
+
19
+ require 'shomen/metadata'
20
+ require 'shomen/model' # TODO: have metadata in model
21
+ require 'shomen/rdoc/extensions'
22
+
23
+ # Shomen Adaptor for RDoc utilizes the rdoc tool to parse ruby source code
24
+ # to build a Shomen documenation file.
25
+ #
26
+ # RDoc is almost entirely a free-form documentation system, so it is not
27
+ # possible for Shomen to fully harness all the details it can support from
28
+ # the RDoc documentation, such as method argument descriptions.
29
+
30
+ class RDoc::Generator::Shomen
31
+
32
+ # Register shomen generator with RDoc.
33
+ RDoc::RDoc.add_generator(self)
34
+
35
+ #include RDocShomen::Metadata
36
+
37
+ # Standard generator factory method.
38
+ def self.for(options)
39
+ new(options)
40
+ end
41
+
42
+ # User options from the command line.
43
+ attr :options
44
+
45
+ # List of all classes and modules.
46
+ #def all_classes_and_modules
47
+ # @all_classes_and_modules ||= RDoc::TopLevel.all_classes_and_modules
48
+ #end
49
+
50
+ # In the world of the RDoc Generators #classes is the same
51
+ # as #all_classes_and_modules. Well, except that its sorted
52
+ # too. For classes sans modules, see #types.
53
+
54
+ def classes
55
+ @classes ||= RDoc::TopLevel.all_classes_and_modules.sort
56
+ end
57
+
58
+ # Only toplevel classes and modules.
59
+ def classes_toplevel
60
+ @classes_toplevel ||= classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
61
+ end
62
+
63
+ #
64
+ def files
65
+ @files ||= (
66
+ @files_rdoc.select{ |f| f.parser != RDoc::Parser::Simple }
67
+ )
68
+ end
69
+
70
+ # List of toplevel files. RDoc supplies this via the #generate method.
71
+ def files_toplevel
72
+ @files_toplevel ||= (
73
+ @files_rdoc.select{ |f| f.parser == RDoc::Parser::Simple }
74
+ )
75
+ end
76
+
77
+ #
78
+
79
+ def files_hash
80
+ @files ||= RDoc::TopLevel.files_hash
81
+ end
82
+
83
+ # List of all methods in all classes and modules.
84
+ def methods_all
85
+ @methods_all ||= classes.map{ |m| m.method_list }.flatten.sort
86
+ end
87
+
88
+ # List of all attributes in all classes and modules.
89
+ def attributes_all
90
+ @attributes_all ||= classes.map{ |m| m.attributes }.flatten.sort
91
+ end
92
+
93
+ #
94
+ def constants_all
95
+ @constants_all ||= classes.map{ |c| c.constants }.flatten
96
+ end
97
+
98
+ ## TODO: What's this then?
99
+ ##def json_creatable?
100
+ ## RDoc::TopLevel.json_creatable?
101
+ ##end
102
+
103
+ # RDoc needs this to function.
104
+ def class_dir ; nil ; end
105
+
106
+ # RDoc needs this to function.
107
+ def file_dir ; nil ; end
108
+
109
+ # TODO: Rename ?
110
+ def shomen
111
+ @table || {}
112
+ end
113
+
114
+ # Build the initial indices and output objects
115
+ # based on an array of top level objects containing
116
+ # the extracted information.
117
+ def generate(files)
118
+ @files_rdoc = files.sort
119
+
120
+ @table = {}
121
+
122
+ generate_metadata
123
+ generate_constants
124
+ generate_classes
125
+ #generate_attributes
126
+ generate_methods
127
+ generate_documents
128
+ generate_scripts # must be last b/c it depends on the others
129
+
130
+ # TODO: method accessor fields need to be handled
131
+
132
+ # THINK: Internal referencing model, YAML and JSYNC ?
133
+ #ref_table = reference_table(@table)
134
+
135
+ #rescue StandardError => err
136
+ # debug_msg "%s: %s\n %s" % [ err.class.name, err.message, err.backtrace.join("\n ") ]
137
+ # raise err
138
+ end
139
+
140
+
141
+ protected
142
+
143
+ #
144
+ def initialize(options)
145
+ @options = options
146
+ #@options.diagram = false # why?
147
+
148
+ @path_base = Pathname.pwd.expand_path
149
+
150
+ # TODO: This is probably not needed any more.
151
+ @path_output = Pathname.new(@options.op_dir).expand_path(@path_base)
152
+ end
153
+
154
+ # Current pathname.
155
+ attr :path_base
156
+
157
+ # The output path.
158
+ attr :path_output
159
+
160
+ #
161
+ def path_output_relative(path=nil)
162
+ if path
163
+ path.to_s.sub(path_base.to_s+'/', '')
164
+ else
165
+ @path_output_relative ||= path_output.to_s.sub(path_base.to_s+'/', '')
166
+ end
167
+ end
168
+
169
+ #
170
+ def generate_metadata
171
+ metadata = Shomen::Metadata.new
172
+ @table['(metadata)'] = metadata.to_h
173
+ end
174
+
175
+ # Add constants to table.
176
+ def generate_constants
177
+ debug_msg "Generating constant documentation:"
178
+ constants_all.each do |rdoc|
179
+ model = Shomen::Model::Constant.new
180
+
181
+ model.path = rdoc.parent.full_name + '::' + rdoc.name
182
+ model.name = rdoc.name
183
+ model.namespace = rdoc.parent.full_name
184
+ model.comment = rdoc.comment
185
+ model.format = 'rdoc'
186
+ model.value = rdoc.value
187
+ model.files = ["/#{rdoc.file.full_name}"]
188
+
189
+ @table[model.path] = model.to_h
190
+ end
191
+ end
192
+
193
+ # Add classes (and modules) to table.
194
+ def generate_classes
195
+ debug_msg "Generating class/module documentation:"
196
+
197
+ classes.each do |rdoc_class|
198
+ debug_msg "%s (%s)" % [ rdoc_class.full_name, rdoc_class.path ]
199
+
200
+ if rdoc_class.type=='class'
201
+ model = Shomen::Model::Class.new
202
+ else
203
+ model = Shomen::Model::Module.new
204
+ end
205
+
206
+ model.path = rdoc_class.full_name
207
+ model.name = rdoc_class.name
208
+ model.namespace = rdoc_class.full_name.split('::')[0...-1].join('::')
209
+ model.includes = rdoc_class.includes.map{ |x| x.name } # FIXME: How to "lookup" full name?
210
+ model.extensions = [] # TODO: How to get extensions?
211
+ model.comment = rdoc_class.comment
212
+ model.format = 'rdoc'
213
+ model.constants = rdoc_class.constants.map{ |x| complete_name(x.name, rdoc_class.full_name) }
214
+ model.modules = rdoc_class.modules.map{ |x| complete_name(x.name, rdoc_class.full_name) }
215
+ model.classes = rdoc_class.classes.map{ |x| complete_name(x.name, rdoc_class.full_name) }
216
+ model.methods = rdoc_class.method_list.map{ |m| method_name(m) }.uniq
217
+ model.accessors = rdoc_class.attributes.map{ |a| method_name(a) }.uniq #+ ":#{a.rw}" }.uniq
218
+ model.files = rdoc_class.in_files.map{ |x| "/#{x.full_name}" }
219
+
220
+ if rdoc_class.type == 'class'
221
+ # HACK: No idea why RDoc is returning some weird superclass:
222
+ # <RDoc::NormalClass:0xd924d4 class Object < BasicObject includes: []
223
+ # attributes: [] methods: [#<RDoc::AnyMethod:0xd92b8c Object#fileutils
224
+ # (public)>] aliases: []>
225
+ # Maybe it has something to do with #fileutils?
226
+ model.superclass = (
227
+ case rdoc_class.superclass
228
+ when nil
229
+ when String
230
+ rdoc_class.superclass
231
+ else
232
+ rdoc_class.superclass.full_name
233
+ end
234
+ )
235
+ end
236
+
237
+ @table[model.path] = model.to_h
238
+ end
239
+ end
240
+
241
+ # Transform RDoc methods to Shomen model and add to table.
242
+ #
243
+ # TODO: How to get literal interface separate from call-sequnces?
244
+ def generate_methods
245
+ debug_msg "Generating method documentation:"
246
+
247
+ list = methods_all + attributes_all
248
+
249
+ list.each do |rdoc_method|
250
+ #debug_msg "%s" % [rdoc_method.full_name]
251
+
252
+ #full_name = method_name(m)
253
+ #'prettyname' => m.pretty_name,
254
+ #'type' => m.type, # class or instance
255
+
256
+ model = Shomen::Model::Method.new
257
+
258
+ model.path = method_name(rdoc_method)
259
+ model.name = rdoc_method.name
260
+ model.namespace = rdoc_method.parent_name
261
+ model.comment = rdoc_method.comment
262
+ model.format = 'rdoc'
263
+ model.aliases = rdoc_method.aliases.map{ |a| method_name(a) }
264
+ model.alias_for = method_name(rdoc_method.is_alias_for)
265
+ model.singleton = rdoc_method.singleton
266
+
267
+ model.declarations << rdoc_method.type.to_s #singleton ? 'class' : 'instance'
268
+ model.declarations << rdoc_method.visibility.to_s
269
+
270
+ model.interfaces = []
271
+ if rdoc_method.call_seq
272
+ rdoc_method.call_seq.split("\n").each do |cs|
273
+ cs = cs.to_s.strip
274
+ model.interfaces << parse_interface(cs) unless cs == ''
275
+ end
276
+ end
277
+ model.interfaces << parse_interface("#{rdoc_method.name}#{rdoc_method.params}")
278
+
279
+ model.returns = [] # RDoc doesn't support specifying return values
280
+ model.file = '/'+rdoc_method.source_code_location.first
281
+ model.line = rdoc_method.source_code_location.last.to_i
282
+ model.source = rdoc_method.source_code_raw
283
+
284
+ if rdoc_method.respond_to?(:c_function)
285
+ model.language = rdoc_method.c_function ? 'c' : 'ruby'
286
+ else
287
+ model.language = 'ruby'
288
+ end
289
+
290
+ @table[model.path] = model.to_h
291
+ end
292
+ end
293
+
294
+ #--
295
+ =begin
296
+ #
297
+ def generate_attributes
298
+ #$stderr.puts "HERE!"
299
+ #$stderr.puts attributes_all.inspect
300
+ #exit
301
+ debug_msg "Generating attributes documentation:"
302
+ attributes_all.each do |rdoc_attribute|
303
+ debug_msg "%s" % [rdoc_attribute.full_name]
304
+
305
+ adapter = Shomen::RDoc::MethodAdapter.new(rdoc_attribute)
306
+ data = Shomen::Model::Method.new(adapter).to_h
307
+
308
+ @table[data['path']] = data
309
+
310
+ #code = m.source_code_raw
311
+ #file, line = m.source_code_location
312
+
313
+ #full_name = method_name(m)
314
+
315
+ #'prettyname' => m.pretty_name,
316
+ #'type' => m.type, # class or instance
317
+
318
+ #model_class = m.singleton ? Shomen::Model::Function : Shomen::Model::Method
319
+ #model_class = Shomen::Model::Attribute
320
+
321
+ #@table[full_name] = model_class.new(
322
+ # 'path' => full_name,
323
+ # 'name' => m.name,
324
+ # 'namespace' => m.parent_name,
325
+ # 'comment' => m.comment,
326
+ # 'access' => m.visibility.to_s,
327
+ # 'rw' => m.rw, # TODO: better name ?
328
+ # 'singleton' => m.singleton,
329
+ # 'aliases' => m.aliases.map{ |a| method_name(a) },
330
+ # 'alias_for' => method_name(m.is_alias_for),
331
+ # 'image' => m.params,
332
+ # 'arguments' => [],
333
+ # 'parameters' => [],
334
+ # 'block' => m.block_params, # TODO: what is block?
335
+ # 'interface' => m.arglists,
336
+ # 'returns' => [],
337
+ # 'file' => file,
338
+ # 'line' => line,
339
+ # 'source' => code
340
+ #).to_h
341
+ end
342
+ end
343
+ =end
344
+ #++
345
+
346
+ # Parse method interface.
347
+ #
348
+ # TODO: remove any trailing comment too
349
+ def parse_interface(interface)
350
+ args, block = [], {}
351
+
352
+ interface, returns = interface.split(/[=-]\>/)
353
+ interface = interface.strip
354
+ if i = interface.index(/\)\s*\{/)
355
+ block['signature'] = interface[i+1..-1].strip
356
+ interface = interface[0..i].strip
357
+ end
358
+
359
+ arguments = interface.strip.sub(/^.*?\(/,'').chomp(')')
360
+ arguments = arguments.split(/\s*\,\s*/)
361
+ arguments.each do |a|
362
+ if a.start_with?('&')
363
+ block['name'] = a
364
+ else
365
+ n,v = a.split('=')
366
+ args << (v ? {'name'=>n,'default'=>v} : {'name'=>n})
367
+ end
368
+ end
369
+
370
+ result = {}
371
+ result['signature'] = interface
372
+ result['arguments'] = args
373
+ result['block'] = block unless block.empty?
374
+ result['returns'] = returns.strip if returns
375
+ return result
376
+ end
377
+ private :parse_interface
378
+
379
+ # Generate entries for information files, e.g. `README.rdoc`.
380
+ def generate_documents
381
+ files_toplevel.each do |rdoc_document|
382
+ absolute_path = File.join(path_base, rdoc_document.full_name)
383
+
384
+ model = Shomen::Model::Document.new
385
+
386
+ model.path = rdoc_document.full_name
387
+ model.name = File.basename(absolute_path)
388
+ model.mtime = File.mtime(absolute_path)
389
+ model.text = File.read(absolute_path) #file.comment
390
+ model.format = mime_type(absolute_path)
391
+
392
+ @table['/'+model.path] = model.to_h
393
+ end
394
+ end
395
+
396
+ # TODO: Add loadpath and make file path relative to it?
397
+
398
+ # Generate script entries.
399
+ def generate_scripts
400
+ #debug_msg "Generating file documentation in #{path_output_relative}:"
401
+ #templatefile = self.path_template + 'file.rhtml'
402
+
403
+ files.each do |rdoc_file|
404
+ debug_msg "%s" % [rdoc_file.full_name]
405
+
406
+ absolute_path = File.join(path_base, rdoc_file.full_name)
407
+ #rel_prefix = self.path_output.relative_path_from(outfile.dirname)
408
+
409
+ model = Shomen::Model::Script.new
410
+
411
+ model.path = rdoc_file.full_name
412
+ model.name = File.basename(rdoc_file.full_name)
413
+ model.mtime = File.mtime(absolute_path)
414
+
415
+ if Shomen.source?
416
+ model.source = File.read(absolute_path) #file.comment
417
+ model.language = mime_type(absolute_path)
418
+ end
419
+
420
+ #model.header =
421
+ #model.footer =
422
+ model.requires = rdoc_file.requires.map{ |r| r.name }
423
+ model.constants = rdoc_file.constants.map{ |c| c.full_name }
424
+
425
+ # note that this utilizes the table we are building
426
+ # so it needs to be the last thing done.
427
+ @table.each do |k, h|
428
+ case h['!']
429
+ when 'module'
430
+ model.modules ||= []
431
+ model.modules << k if h['files'].include?(rdoc_file.full_name)
432
+ when 'class'
433
+ model.classes ||= []
434
+ model.classes << k if h['files'].include?(rdoc_file.full_name)
435
+ when 'method'
436
+ model.methods ||= []
437
+ model.methods << k if h['file'] == rdoc_file.full_name
438
+ when 'class-method'
439
+ model.class_methods ||= []
440
+ model.class_methods << k if h['file'] == rdoc_file.full_name
441
+ end
442
+ end
443
+
444
+ @table['/'+model.path] = model.to_h
445
+ end
446
+ end
447
+
448
+ # Returns String of fully qualified name.
449
+ def complete_name(name, namespace)
450
+ if name !~ /^#{namespace}/
451
+ "#{namespace}::#{name}"
452
+ else
453
+ name
454
+ end
455
+ end
456
+
457
+ #
458
+ def collect_methods(class_module, singleton=false)
459
+ list = []
460
+ class_module.method_list.each do |m|
461
+ next if singleton ^ m.singleton
462
+ list << method_name(m)
463
+ end
464
+ list.uniq
465
+ end
466
+
467
+ #
468
+ def collect_attributes(class_module, singleton=false)
469
+ list = []
470
+ class_module.attributes.each do |a|
471
+ next if singleton ^ a.singleton
472
+ #p a.rw
473
+ #case a.rw
474
+ #when :write, 'W'
475
+ # list << "#{method_name(a)}="
476
+ #else
477
+ list << method_name(a)
478
+ #end
479
+ end
480
+ list.uniq
481
+ end
482
+
483
+ #
484
+ def method_name(method)
485
+ return nil if method.nil?
486
+ if method.singleton
487
+ i = method.full_name.rindex('::')
488
+ method.full_name[0...i] + '.' + method.full_name[i+2..-1]
489
+ else
490
+ method.full_name
491
+ end
492
+ end
493
+
494
+ #
495
+ def mime_type(path)
496
+ case File.extname(path)
497
+ when '.rb', '.rbx' then 'text/ruby'
498
+ when '.c' then 'text/c-source'
499
+ when '.rdoc' then 'text/rdoc'
500
+ when '.md', '.markdown' then 'text/markdown'
501
+ else 'text/plain'
502
+ end
503
+ end
504
+
505
+ # Output progress information if rdoc debugging is enabled
506
+
507
+ def debug_msg(msg)
508
+ return unless $DEBUG_RDOC
509
+ case msg[-1,1]
510
+ when '.' then tab = "= "
511
+ when ':' then tab = "== "
512
+ else tab = "* "
513
+ end
514
+ $stderr.puts(tab + msg)
515
+ end
516
+
517
+ end
518
+
519
+
520
+
521
+ #--
522
+ =begin
523
+ #
524
+ # N O T U S E D
525
+ #
526
+
527
+ # Sort based on how often the top level namespace occurs, and then on the
528
+ # name of the module -- this works for projects that put their stuff into
529
+ # a namespace, of course, but doesn't hurt if they don't.
530
+ def sort_salient(classes)
531
+ nscounts = classes.inject({}) do |counthash, klass|
532
+ top_level = klass.full_name.gsub( /::.*/, '' )
533
+ counthash[top_level] ||= 0
534
+ counthash[top_level] += 1
535
+ counthash
536
+ endfiles_toplevel
537
+ classes.sort_by{ |klass|
538
+ top_level = klass.full_name.gsub( /::.*/, '' )
539
+ [nscounts[top_level] * -1, klass.full_name]
540
+ }.select{ |klass|
541
+ klass.document_self
542
+ }
543
+ end
544
+ =end
545
+
546
+ =begin
547
+ # Loop through table and convert all named references into bonofied object
548
+ # references.
549
+ def reference_table(table)
550
+ debug_msg "== Generating Reference Table"
551
+ new_table = {}
552
+ table.each do |key, entry|
553
+ debug_msg "%s" % [key]
554
+ data = entry.dup
555
+ new_table[key] = data
556
+ case data['!']
557
+ when 'script'
558
+ data["constants"] = ref_list(data["constants"])
559
+ data["modules"] = ref_list(data["modules"])
560
+ data["classes"] = ref_list(data["classes"])
561
+ data["functions"] = ref_list(data["functions"])
562
+ data["methods"] = ref_list(data["methods"])
563
+ when 'file'
564
+ when 'constant'
565
+ data["namespace"] = ref_item(data["namespace"])
566
+ when 'module', 'class'
567
+ data["namespace"] = ref_item(data["namespace"])
568
+ data["includes"] = ref_list(data["includes"])
569
+ #data["extended"] = ref_list(data["extended"])
570
+ data["constants"] = ref_list(data["constants"])
571
+ data["modules"] = ref_list(data["modules"])
572
+ data["classes"] = ref_list(data["classes"])
573
+ data["functions"] = ref_list(data["functions"])
574
+ data["methods"] = ref_list(data["methods"])
575
+ data["files"] = ref_list(data["files"])
576
+ data["superclass"] = ref_item(data["superclass"]) if data.key?("superclass")
577
+ when 'method', 'function'
578
+ data["namespace"] = ref_item(data["namespace"])
579
+ data["file"] = ref_item(data["file"])
580
+ end
581
+ end
582
+ new_table
583
+ end
584
+
585
+ # Given a key, return the matching table item. If not found return the key.
586
+ def ref_item(key)
587
+ @table[key] || key
588
+ end
589
+
590
+ # Given a list of keys, return the matching table items.
591
+ def ref_list(keys)
592
+ #keys.map{ |k| @table[k] || k }
593
+ keys.map{ |k| @table[k] || nil }.compact
594
+ end
595
+
596
+ =end
597
+ #++
598
+