shomen-rdoc 0.1.0
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.
- data/.ruby +59 -0
- data/HISTORY.rdoc +14 -0
- data/LICENSE.txt +29 -0
- data/README.rdoc +6 -0
- data/bin/shomen-rdoc +3 -0
- data/lib/shomen-rdoc.rb +26 -0
- data/lib/shomen-rdoc.yml +59 -0
- data/lib/shomen-rdoc/command.rb +151 -0
- data/lib/shomen-rdoc/generator.rb +900 -0
- data/lib/shomen-rdoc/rdoc_ext.rb +149 -0
- data/spec/02_class.rdoc +63 -0
- data/spec/03_module.rdoc +59 -0
- data/spec/04_constant.rdoc +59 -0
- data/spec/05_method.rdoc +286 -0
- data/spec/10_interface_overloading.rdoc +94 -0
- data/spec/applique/ae.rb +1 -0
- data/spec/applique/shomen.rb +24 -0
- data/spec/fixture/lib/example.rb +52 -0
- metadata +105 -0
data/.ruby
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- meta
|
4
|
+
- meta/
|
5
|
+
authors:
|
6
|
+
- name: trans
|
7
|
+
email: transfire@gmail.com
|
8
|
+
copyrights: []
|
9
|
+
requirements:
|
10
|
+
- name: rdoc
|
11
|
+
version: 3+
|
12
|
+
- name: shomen-model
|
13
|
+
- name: detroit
|
14
|
+
groups:
|
15
|
+
- build
|
16
|
+
development: true
|
17
|
+
dependencies: []
|
18
|
+
alternatives: []
|
19
|
+
conflicts: []
|
20
|
+
repositories:
|
21
|
+
- uri: git://github.com/rubyworks/shomen-rdoc.git
|
22
|
+
scm: git
|
23
|
+
name: upstream
|
24
|
+
resources:
|
25
|
+
- uri: http://rubyworks.github.com/shomen-rdoc
|
26
|
+
name: home
|
27
|
+
type: home
|
28
|
+
- uri: http://github.com/rubyworks/shomen-rdoc/wiki
|
29
|
+
name: docs
|
30
|
+
type: doc
|
31
|
+
- uri: http://github.com/rubyworks/shomen-rdoc
|
32
|
+
name: code
|
33
|
+
type: code
|
34
|
+
- uri: http://github.com/rubyworks/shomen-rdoc/issues
|
35
|
+
name: bugs
|
36
|
+
type: bugs
|
37
|
+
- uri: http://groups.google.com/groups/rubyworks-mailinglist
|
38
|
+
name: mail
|
39
|
+
type: mail
|
40
|
+
- uri: http://chat.us.freenode.net/rubyworks
|
41
|
+
name: chat
|
42
|
+
type: chat
|
43
|
+
extra: {}
|
44
|
+
load_path:
|
45
|
+
- lib
|
46
|
+
revision: 0
|
47
|
+
created: '2010-07-01'
|
48
|
+
summary: Shomen Documentation via RDoc
|
49
|
+
title: Shomen RDoc
|
50
|
+
version: 0.1.0
|
51
|
+
name: shomen-rdoc
|
52
|
+
description: ! 'Shomen RDoc provides a command line utility for generating Shomen
|
53
|
+
standard
|
54
|
+
|
55
|
+
documentation via the RDoc''s `.rdoc` cache. It is an alternative to the
|
56
|
+
|
57
|
+
`rdoc-shomen` format plugin.'
|
58
|
+
organization: rubyworks
|
59
|
+
date: '2012-04-19'
|
data/HISTORY.rdoc
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
= RELEASE HISTORY
|
2
|
+
|
3
|
+
== 0.1.0 / 2012-04-20
|
4
|
+
|
5
|
+
This is the initial public release of Shomen RDoc, spun-off
|
6
|
+
from the main Shomen library.
|
7
|
+
|
8
|
+
Please note that this utility is not in the best of shape
|
9
|
+
due to current issues with RDoc itself.
|
10
|
+
|
11
|
+
Changes:
|
12
|
+
|
13
|
+
* Happy Release Day!
|
14
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Shomen RDoc - Shomen Generator via RDoc Documentation
|
2
|
+
(http://github.com/rubyworks/shomen-rdoc)
|
3
|
+
|
4
|
+
Copyright (c) 2011 Rubyworks. All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms,
|
7
|
+
with or without modification, are permitted provided that the following
|
8
|
+
conditions are met:
|
9
|
+
|
10
|
+
1. Redistributions of source code must retain the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer.
|
12
|
+
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
notice, this list of conditions and the following disclaimer in the
|
15
|
+
documentation and/or other materials provided with the distribution.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
18
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
20
|
+
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
24
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
25
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
26
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
SPDX License: BSD-2-Clause
|
29
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
= Shomen RDoc
|
2
|
+
|
3
|
+
The Shomen RDoc utility is a utility to generate Shomen standard documentation
|
4
|
+
via RDoc's documentation cache (usually stored in `.rdoc`). This is an aternative
|
5
|
+
to using the rdoc-shomen format, which is an RDoc plugin rather then a stand alone
|
6
|
+
tool.
|
data/bin/shomen-rdoc
ADDED
data/lib/shomen-rdoc.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Shomen
|
2
|
+
|
3
|
+
# Shomen Rdoc is used to generate Shomen formatted documentation
|
4
|
+
# from RDoc cache.
|
5
|
+
#
|
6
|
+
module Rdoc
|
7
|
+
#
|
8
|
+
def self.metadata
|
9
|
+
@metadata ||= (
|
10
|
+
require 'yaml'
|
11
|
+
YAML.load_file(File.dirname(__FILE__) + '/shomen-rdoc.yml')
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
def self.const_missing(name)
|
17
|
+
metadata[name.to_s.downcase] || super(name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'shomen-model'
|
24
|
+
require 'shomen-rdoc/generator'
|
25
|
+
require 'shomen-rdoc/command'
|
26
|
+
|
data/lib/shomen-rdoc.yml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- meta
|
4
|
+
- meta/
|
5
|
+
authors:
|
6
|
+
- name: trans
|
7
|
+
email: transfire@gmail.com
|
8
|
+
copyrights: []
|
9
|
+
requirements:
|
10
|
+
- name: rdoc
|
11
|
+
version: 3+
|
12
|
+
- name: shomen-model
|
13
|
+
- name: detroit
|
14
|
+
groups:
|
15
|
+
- build
|
16
|
+
development: true
|
17
|
+
dependencies: []
|
18
|
+
alternatives: []
|
19
|
+
conflicts: []
|
20
|
+
repositories:
|
21
|
+
- uri: git://github.com/rubyworks/shomen-rdoc.git
|
22
|
+
scm: git
|
23
|
+
name: upstream
|
24
|
+
resources:
|
25
|
+
- uri: http://rubyworks.github.com/shomen-rdoc
|
26
|
+
name: home
|
27
|
+
type: home
|
28
|
+
- uri: http://github.com/rubyworks/shomen-rdoc/wiki
|
29
|
+
name: docs
|
30
|
+
type: doc
|
31
|
+
- uri: http://github.com/rubyworks/shomen-rdoc
|
32
|
+
name: code
|
33
|
+
type: code
|
34
|
+
- uri: http://github.com/rubyworks/shomen-rdoc/issues
|
35
|
+
name: bugs
|
36
|
+
type: bugs
|
37
|
+
- uri: http://groups.google.com/groups/rubyworks-mailinglist
|
38
|
+
name: mail
|
39
|
+
type: mail
|
40
|
+
- uri: http://chat.us.freenode.net/rubyworks
|
41
|
+
name: chat
|
42
|
+
type: chat
|
43
|
+
extra: {}
|
44
|
+
load_path:
|
45
|
+
- lib
|
46
|
+
revision: 0
|
47
|
+
created: '2010-07-01'
|
48
|
+
summary: Shomen Documentation via RDoc
|
49
|
+
title: Shomen RDoc
|
50
|
+
version: 0.1.0
|
51
|
+
name: shomen-rdoc
|
52
|
+
description: ! 'Shomen RDoc provides a command line utility for generating Shomen
|
53
|
+
standard
|
54
|
+
|
55
|
+
documentation via the RDoc''s `.rdoc` cache. It is an alternative to the
|
56
|
+
|
57
|
+
`rdoc-shomen` format plugin.'
|
58
|
+
organization: rubyworks
|
59
|
+
date: '2012-04-19'
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Shomen
|
2
|
+
|
3
|
+
module Rdoc
|
4
|
+
|
5
|
+
# TODO: Instead of using command line options for shomen
|
6
|
+
# we could use environment variables. ?
|
7
|
+
|
8
|
+
# The Shomen RDoc command line tool provides a utility to generate
|
9
|
+
# a Shomen documentation file using RDoc's .rdoc cache.
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
#
|
13
|
+
# $ shomen-rdoc --readme README.md lib - [A-Z]*.*
|
14
|
+
#
|
15
|
+
class Command
|
16
|
+
require 'optparse'
|
17
|
+
|
18
|
+
# Public: Shortcut for `CLI.new(*argv).run`.
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
def self.run(*argv)
|
22
|
+
new(*argv).run
|
23
|
+
end
|
24
|
+
|
25
|
+
# Command line options.
|
26
|
+
attr :options
|
27
|
+
|
28
|
+
# Initialize new command.
|
29
|
+
#
|
30
|
+
# argv - Command line arguments. [Array]
|
31
|
+
#
|
32
|
+
# Returns CLI instance.
|
33
|
+
def initialize(*argv)
|
34
|
+
@options = {}
|
35
|
+
|
36
|
+
parse(argv)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Public: Run command.
|
40
|
+
#
|
41
|
+
# Returns nothing.
|
42
|
+
def run
|
43
|
+
generator = Generator.new(options)
|
44
|
+
$stdout.puts generator
|
45
|
+
end
|
46
|
+
|
47
|
+
# Parse command line arguments.
|
48
|
+
#
|
49
|
+
# argv - List of command line arguments. [Array]
|
50
|
+
#
|
51
|
+
# Returns list of arguments. [Array]
|
52
|
+
#
|
53
|
+
def parse(argv)
|
54
|
+
if i = argv.index('-')
|
55
|
+
options[:documents] = argv[i+1..-1]
|
56
|
+
argv = argv[0...i]
|
57
|
+
end
|
58
|
+
|
59
|
+
parser = OptionParser.new
|
60
|
+
parser_options(parser)
|
61
|
+
parser.parse!(argv)
|
62
|
+
|
63
|
+
if !(force? or root?)
|
64
|
+
$stderr.puts "ERROR: Not a project directory. Use --force to override."
|
65
|
+
exit -1
|
66
|
+
end
|
67
|
+
|
68
|
+
options[:scripts] = argv
|
69
|
+
end
|
70
|
+
|
71
|
+
# Define command line options.
|
72
|
+
#
|
73
|
+
# parser - Instance of {OptionParser}.
|
74
|
+
#
|
75
|
+
# Returns nothing.
|
76
|
+
def parser_options(parser)
|
77
|
+
parser.on('-j', '--json', 'output JSON instead of YAML (default)') do
|
78
|
+
options[:format] = :json
|
79
|
+
end
|
80
|
+
parser.on('-y', '--yaml', 'output YAML instead of JSON') do
|
81
|
+
options[:format] = :yaml
|
82
|
+
end
|
83
|
+
|
84
|
+
parser.on('-d', '--db DIR', 'documentation store directory (deafult is `.rdoc` or `.yardoc`)') do |dir|
|
85
|
+
options[:store] = dir
|
86
|
+
end
|
87
|
+
parser.on('-c', '--use-cache', 'do not regenerate docs, use pre-existing cache') do
|
88
|
+
options[:use_cache] = true
|
89
|
+
end
|
90
|
+
|
91
|
+
parser.on('-s', '--source', 'include full source in script documentation') do
|
92
|
+
options[:source] = true
|
93
|
+
end
|
94
|
+
parser.on('-w', '--webcvs URI', 'prefix link to source code') do |uri|
|
95
|
+
options[:webcvs] = uri
|
96
|
+
end
|
97
|
+
parser.on('-r', '--readme FILE', 'which file to use as main') do |file|
|
98
|
+
options[:readme] = file
|
99
|
+
end
|
100
|
+
|
101
|
+
#parser.on('--save', 'save options for future use') do |markup|
|
102
|
+
# options[:save] = true
|
103
|
+
#end
|
104
|
+
|
105
|
+
# TODO: shouldn't this be in .yardopts?
|
106
|
+
parser.on('--markup TYPE', 'markup type used for comments (rdoc, md, tomdoc)') do |markup|
|
107
|
+
options[:markup] = markup.to_sym
|
108
|
+
end
|
109
|
+
|
110
|
+
parser.on('-F', '--force') do
|
111
|
+
$FORCE = true
|
112
|
+
end
|
113
|
+
|
114
|
+
parser.on_tail('--debug', 'run with $DEBUG set to true') do
|
115
|
+
$DEBUG = true
|
116
|
+
end
|
117
|
+
parser.on_tail('--warn', 'run with $VERBOSE set to true') do
|
118
|
+
$VERBOSE = true
|
119
|
+
end
|
120
|
+
|
121
|
+
parser.on_tail('--help', 'see this help message') do
|
122
|
+
puts parser; exit -1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Is `$FORCE` set?
|
127
|
+
#
|
128
|
+
# Returns true or false.
|
129
|
+
def force?
|
130
|
+
!!$FORCE
|
131
|
+
end
|
132
|
+
|
133
|
+
# Is this a project directory?
|
134
|
+
#
|
135
|
+
# Returns true or false.
|
136
|
+
def root?
|
137
|
+
root = false
|
138
|
+
root = true if File.exist?('.ruby')
|
139
|
+
root = true if File.exist?('.yardoc')
|
140
|
+
root = true if File.exist?('.rdoc')
|
141
|
+
root = true if File.exist?('.git')
|
142
|
+
root = true if File.exist?('.hg')
|
143
|
+
root = true if File.exist?('_darcs')
|
144
|
+
root
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
@@ -0,0 +1,900 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Shomen
|
4
|
+
|
5
|
+
module Rdoc
|
6
|
+
|
7
|
+
# TODO: what about reading options from .document and .rdoc_options ?
|
8
|
+
# also rdoc.options[:document] ?
|
9
|
+
|
10
|
+
# This adapter is used to convert RDoc's documentation extracted
|
11
|
+
# from a local store (`.rdoc`) to Shomen's pure-data format.
|
12
|
+
#
|
13
|
+
# There's a bit of a limitation with adding scripts to the Shomen
|
14
|
+
# table, as it appears rdoc only keeps track of script files for methods.
|
15
|
+
# So any file thet doesn't contain at least one method definition won't
|
16
|
+
# show up. We'll see if we can fix this in a future version.
|
17
|
+
#
|
18
|
+
# In addition, documentation files are not tracked at all, so they have
|
19
|
+
# to provided on the command line regardless --though by default any
|
20
|
+
# README file will be included.
|
21
|
+
#
|
22
|
+
# WARNING: RDoc's RI::Store has some issues and presently some information
|
23
|
+
# is not accessible that otherwise would be included. B/c of this we recommend
|
24
|
+
# using the traditional `rdoc-shomen` generator instead until these issues
|
25
|
+
# are resolved.
|
26
|
+
#
|
27
|
+
class Generator < Shomen::Generator
|
28
|
+
|
29
|
+
# Initialize new RDoc adaptor.
|
30
|
+
def initialize(options)
|
31
|
+
initialize_rdoc
|
32
|
+
|
33
|
+
@store = '.rdoc'
|
34
|
+
|
35
|
+
super(options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Load RDoc library. Must be RDoc v3 or greater. We invoke the `gem` method
|
39
|
+
# in this method in order to ensure we are not using the rdoc library included
|
40
|
+
# with the Ruby distribution, which is out of date.
|
41
|
+
#
|
42
|
+
# Returns nothing.
|
43
|
+
def initialize_rdoc
|
44
|
+
gem 'rdoc', '>3' # rescue nil
|
45
|
+
require 'rdoc'
|
46
|
+
require 'shomen-rdoc/rdoc_ext'
|
47
|
+
end
|
48
|
+
|
49
|
+
# Location to of RDoc documentation cache. This defaults to `.rdoc` which is
|
50
|
+
# where RDoc normally places it's generated documentation files.
|
51
|
+
#
|
52
|
+
# Returns String path to RDoc documentation cache.
|
53
|
+
attr_accessor :store
|
54
|
+
|
55
|
+
# Use pre-existant cache instead of regenerating documentation.
|
56
|
+
attr_accessor :use_cache
|
57
|
+
|
58
|
+
# Use pre-existant cache instead of regenerating documentation.
|
59
|
+
#
|
60
|
+
# Returns true/false.
|
61
|
+
def use_cache?
|
62
|
+
@use_cache
|
63
|
+
end
|
64
|
+
|
65
|
+
# Files to be documented.
|
66
|
+
#
|
67
|
+
# Returns Array of file paths.
|
68
|
+
def files
|
69
|
+
@files ||= (
|
70
|
+
list = []
|
71
|
+
list.concat scripts
|
72
|
+
list.concat documents
|
73
|
+
list.concat(['README*']) if list.empty? #['lib', 'README*'] ?
|
74
|
+
list
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Generate with RDoc as backend processor.
|
79
|
+
#
|
80
|
+
# Returns documentation table. [Hash]
|
81
|
+
def generate
|
82
|
+
preconfigure unless use_cache?
|
83
|
+
generate_table
|
84
|
+
end
|
85
|
+
|
86
|
+
# The hash object that is used to store the generated
|
87
|
+
# documentation.
|
88
|
+
#
|
89
|
+
# Returns documentation table. [Hash]
|
90
|
+
def table
|
91
|
+
@table
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
# Produce RDoc cache.
|
97
|
+
#
|
98
|
+
# Returns nothing.
|
99
|
+
def preconfigure
|
100
|
+
argv = []
|
101
|
+
argv.concat ["-D"] if $DEBUG
|
102
|
+
argv.concat ["-q"]
|
103
|
+
argv.concat ["-r"]
|
104
|
+
argv.concat ["-o", store]
|
105
|
+
argv.concat ["--markup", markup] if markup
|
106
|
+
#argv.concat ["--write-options"] #if save
|
107
|
+
argv.concat scripts
|
108
|
+
#argv.concat ['-', *documents] unless documents.empty?
|
109
|
+
|
110
|
+
rdoc = ::RDoc::RDoc.new
|
111
|
+
$stderr.puts('rdoc ' + argv.join(' ')) if $DEBUG
|
112
|
+
|
113
|
+
rdoc.document(argv)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Generate documentation table from RDoc.
|
117
|
+
#
|
118
|
+
# Returns documentation table. [Hash]
|
119
|
+
def generate_table
|
120
|
+
#options = {}
|
121
|
+
#options[:files] = documents # + scripts
|
122
|
+
#options[:store] = store
|
123
|
+
#options[:webcvs] = webcvs
|
124
|
+
#options[:source] = source
|
125
|
+
|
126
|
+
#rdoc = Shomen::RDocAdaptor.new(options)
|
127
|
+
#rdoc.generate
|
128
|
+
|
129
|
+
if not File.exist?(store)
|
130
|
+
$stderr.puts "ERROR: RDoc store not found -- '#{store}`."
|
131
|
+
exit -1
|
132
|
+
end
|
133
|
+
|
134
|
+
@table = {}
|
135
|
+
|
136
|
+
constants = []
|
137
|
+
scripts = []
|
138
|
+
|
139
|
+
db = ::RDoc::RI::Store.new(store)
|
140
|
+
db.load_cache
|
141
|
+
|
142
|
+
generate_metadata
|
143
|
+
|
144
|
+
debug_msg "Generating class/module documentation:"
|
145
|
+
db.modules.each do |name|
|
146
|
+
object = db.load_class(name)
|
147
|
+
constants.concat(object.constants)
|
148
|
+
generate_class(object)
|
149
|
+
end
|
150
|
+
|
151
|
+
debug_msg "Generating class method documentation:"
|
152
|
+
db.class_methods.each do |module_name, methods|
|
153
|
+
methods.each do |name|
|
154
|
+
object = db.load_method(module_name, name)
|
155
|
+
scripts.push(object.file)
|
156
|
+
generate_method(object)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
debug_msg "Generating instance method documentation:"
|
161
|
+
db.instance_methods.each do |module_name, methods|
|
162
|
+
methods.each do |name|
|
163
|
+
object = db.load_method(module_name, "##{name}")
|
164
|
+
scripts.push(object.file)
|
165
|
+
generate_method(object)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#debug_msg "Generating attribute method documentation:"
|
170
|
+
#db.attributes.each do |module_name, methods|
|
171
|
+
# methods.each do |name|
|
172
|
+
# object = db.load_method(module_name, "##{name}")
|
173
|
+
# generate_method(object)
|
174
|
+
# end
|
175
|
+
#end
|
176
|
+
|
177
|
+
debug_msg "Generating constant documentation:"
|
178
|
+
constants.each do |object|
|
179
|
+
generate_constant(object)
|
180
|
+
end
|
181
|
+
|
182
|
+
debug_msg "Generating file documentation:"
|
183
|
+
# TODO: Are c/c++ sourse files working okay?
|
184
|
+
# TODO: Add a generator for non-ruby script (e.g. .js)?
|
185
|
+
collect_files.each do |file|
|
186
|
+
case File.extname(file)
|
187
|
+
when '.rb', '.rbx', '.c', '.cpp'
|
188
|
+
generate_script(file)
|
189
|
+
when '.rdoc', '.md', '.markdown', '.txt'
|
190
|
+
generate_document(file)
|
191
|
+
else
|
192
|
+
generate_document(file)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
debug_msg "Generating script documentation:"
|
197
|
+
scripts.each do |object|
|
198
|
+
generate_script(object)
|
199
|
+
end
|
200
|
+
|
201
|
+
return @table
|
202
|
+
end
|
203
|
+
|
204
|
+
# Collect files given list of +globs+.
|
205
|
+
#
|
206
|
+
# Returns Array of files.
|
207
|
+
def collect_files
|
208
|
+
globs = self.files
|
209
|
+
globs = globs.map{ |glob| Dir[glob] }.flatten.uniq
|
210
|
+
globs = globs.map do |glob|
|
211
|
+
if File.directory?(glob)
|
212
|
+
Dir[File.join(glob, '**/*')]
|
213
|
+
else
|
214
|
+
glob
|
215
|
+
end
|
216
|
+
end
|
217
|
+
list = globs.flatten.uniq.compact
|
218
|
+
list = list.reject{ |path| File.extname(path) == '.html' }
|
219
|
+
list = list.select{ |path| File.file?(path) }
|
220
|
+
list
|
221
|
+
end
|
222
|
+
|
223
|
+
# Generate project metadata entry.
|
224
|
+
#
|
225
|
+
# Returns Hash of metadata, as added to the documentation table
|
226
|
+
def generate_metadata
|
227
|
+
#project_metadata = Metadata.new
|
228
|
+
@table['(metadata)'] = project_metadata.to_h
|
229
|
+
end
|
230
|
+
|
231
|
+
# Add constant to table.
|
232
|
+
#
|
233
|
+
# rdoc_constant - RDoc constant documentation object.
|
234
|
+
#
|
235
|
+
# Returns Hash for constant documentation entry.
|
236
|
+
def generate_constant(rdoc_constant)
|
237
|
+
debug_msg " #{rdoc_constant.name}"
|
238
|
+
|
239
|
+
model = Shomen::Model::Constant.new
|
240
|
+
|
241
|
+
model.path = rdoc_constant.parent.full_name + '::' + rdoc_constant.name
|
242
|
+
model.name = rdoc_constant.name
|
243
|
+
model.namespace = rdoc_constant.parent.full_name
|
244
|
+
model.comment = comment(rdoc_constant.comment)
|
245
|
+
model.format = 'rdoc' # or tomdoc ?
|
246
|
+
model.value = rdoc_constant.value
|
247
|
+
model.files = ["/#{rdoc_constant.file.full_name}"]
|
248
|
+
|
249
|
+
@table[model.path] = model.to_h
|
250
|
+
end
|
251
|
+
|
252
|
+
# Add classes (and modules) to table.
|
253
|
+
#
|
254
|
+
# rdoc_class - RDoc class documentation object.
|
255
|
+
#
|
256
|
+
# Returns Hash of class or module documentation entry.
|
257
|
+
def generate_class(rdoc_class)
|
258
|
+
debug_msg " %s" % [ rdoc_class.full_name ]
|
259
|
+
|
260
|
+
if rdoc_class.type=='class'
|
261
|
+
model = Shomen::Model::Class.new
|
262
|
+
else
|
263
|
+
model = Shomen::Model::Module.new
|
264
|
+
end
|
265
|
+
|
266
|
+
modules = (rdoc_class.modules_hash || {}).values
|
267
|
+
classes = (rdoc_class.classes_hash || {}).values
|
268
|
+
|
269
|
+
model.path = rdoc_class.full_name
|
270
|
+
model.name = rdoc_class.name
|
271
|
+
model.namespace = rdoc_class.full_name.split('::')[0...-1].join('::')
|
272
|
+
model.includes = rdoc_class.includes.map{ |x| x.name } # FIXME: How to "lookup" full name?
|
273
|
+
model.extensions = [] # TODO: How to get extension modules?
|
274
|
+
model.comment = comment(rdoc_class.comment)
|
275
|
+
model.format = 'rdoc' # or tomdoc ?
|
276
|
+
model.constants = rdoc_class.constants.map{ |x| complete_name(x.name, rdoc_class.full_name) }
|
277
|
+
|
278
|
+
model.modules = modules.map{ |x| complete_name(x.name, rdoc_class.full_name) }
|
279
|
+
model.classes = classes.map{ |x| complete_name(x.name, rdoc_class.full_name) }
|
280
|
+
|
281
|
+
model.methods = rdoc_class.method_list.map{ |m| method_name(m) }.uniq
|
282
|
+
model.accessors = rdoc_class.attributes.map{ |a| method_name(a) }.uniq #+ ":#{a.rw}" }.uniq
|
283
|
+
|
284
|
+
model.files = (rdoc_class.in_files || []).map{ |x| "/#{x.full_name}" }
|
285
|
+
|
286
|
+
if rdoc_class.file
|
287
|
+
model.files.unshift("/#{rdoc_class.file.full_name}")
|
288
|
+
end
|
289
|
+
|
290
|
+
if rdoc_class.type == 'class'
|
291
|
+
# HACK: No idea why RDoc is returning some weird superclass:
|
292
|
+
# <RDoc::NormalClass:0xd924d4 class Object < BasicObject includes: []
|
293
|
+
# attributes: [] methods: [#<RDoc::AnyMethod:0xd92b8c Object#fileutils
|
294
|
+
# (public)>] aliases: []>
|
295
|
+
# Maybe it has something to do with #fileutils?
|
296
|
+
model.superclass = (
|
297
|
+
case rdoc_class.superclass
|
298
|
+
when nil
|
299
|
+
when String
|
300
|
+
rdoc_class.superclass
|
301
|
+
else
|
302
|
+
rdoc_class.superclass.full_name
|
303
|
+
end
|
304
|
+
)
|
305
|
+
end
|
306
|
+
|
307
|
+
@table[model.path] = model.to_h
|
308
|
+
end
|
309
|
+
|
310
|
+
# TODO: How to get literal interface separate from call-sequences?
|
311
|
+
|
312
|
+
# Transform RDoc method to Shomen model and add to table.
|
313
|
+
#
|
314
|
+
# rdoc_method - RDoc method documentation object.
|
315
|
+
#
|
316
|
+
# Returns Hash of method documentation entry.
|
317
|
+
def generate_method(rdoc_method)
|
318
|
+
#list = methods_all + attributes_all
|
319
|
+
|
320
|
+
#debug_msg "%s" % [rdoc_method.full_name]
|
321
|
+
|
322
|
+
#full_name = method_name(m)
|
323
|
+
#'prettyname' => m.pretty_name,
|
324
|
+
#'type' => m.type, # class or instance
|
325
|
+
|
326
|
+
model = Shomen::Model::Method.new
|
327
|
+
|
328
|
+
model.path = method_name(rdoc_method)
|
329
|
+
model.name = rdoc_method.name
|
330
|
+
model.namespace = rdoc_method.parent_name
|
331
|
+
model.comment = comment(rdoc_method.comment)
|
332
|
+
model.format = 'rdoc' # or tomdoc ?
|
333
|
+
model.aliases = (rdoc_method.aliases || []).map{ |a| method_name(a) }
|
334
|
+
model.alias_for = method_name(rdoc_method.is_alias_for)
|
335
|
+
model.singleton = rdoc_method.singleton
|
336
|
+
|
337
|
+
model.declarations << rdoc_method.type.to_s #singleton ? 'class' : 'instance'
|
338
|
+
model.declarations << rdoc_method.visibility.to_s
|
339
|
+
|
340
|
+
model.interfaces = []
|
341
|
+
if rdoc_method.call_seq
|
342
|
+
rdoc_method.call_seq.split("\n").each do |cs|
|
343
|
+
cs = cs.to_s.strip
|
344
|
+
model.interfaces << parse_interface(cs) unless cs == ''
|
345
|
+
end
|
346
|
+
end
|
347
|
+
model.interfaces << parse_interface("#{rdoc_method.name}#{rdoc_method.params}")
|
348
|
+
|
349
|
+
model.returns = [] # RDoc doesn't support specifying return values
|
350
|
+
model.file = '/' + rdoc_method.file_name
|
351
|
+
model.line = rdoc_method.line.to_i # FIXME: why is this always zero?
|
352
|
+
model.source = rdoc_method.source_code_raw
|
353
|
+
|
354
|
+
if rdoc_method.respond_to?(:c_function)
|
355
|
+
model.language = rdoc_method.c_function ? 'c' : 'ruby'
|
356
|
+
else
|
357
|
+
model.language = 'ruby'
|
358
|
+
end
|
359
|
+
|
360
|
+
@table[model.path] = model.to_h
|
361
|
+
end
|
362
|
+
|
363
|
+
# TODO: remove any trailing comment from interface
|
364
|
+
|
365
|
+
# Parse method interface.
|
366
|
+
#
|
367
|
+
# interface - String representation of method interface.
|
368
|
+
#
|
369
|
+
# Returns Hash entry of method interface.
|
370
|
+
def parse_interface(interface)
|
371
|
+
args, block = [], {}
|
372
|
+
|
373
|
+
interface, returns = interface.split(/[=-]\>/)
|
374
|
+
interface = interface.strip
|
375
|
+
if i = interface.index(/\)\s*\{/)
|
376
|
+
block['image'] = interface[i+1..-1].strip
|
377
|
+
interface = interface[0..i].strip
|
378
|
+
end
|
379
|
+
|
380
|
+
arguments = interface.strip.sub(/^.*?\(/,'').chomp(')')
|
381
|
+
arguments = arguments.split(/\s*\,\s*/)
|
382
|
+
arguments.each do |a|
|
383
|
+
if a.start_with?('&')
|
384
|
+
block['name'] = a
|
385
|
+
else
|
386
|
+
n,v = a.split('=')
|
387
|
+
args << (v ? {'name'=>n,'default'=>v} : {'name'=>n})
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
result = {}
|
392
|
+
result['signature'] = interface
|
393
|
+
result['arguments'] = args
|
394
|
+
result['block'] = block unless block.empty?
|
395
|
+
result['returns'] = returns.strip if returns
|
396
|
+
return result
|
397
|
+
end
|
398
|
+
|
399
|
+
# Generate entries for information files, e.g. `README.rdoc`.
|
400
|
+
#
|
401
|
+
# rdoc_document - RDoc file documentation object.
|
402
|
+
#
|
403
|
+
# Returns Hash of document entry.
|
404
|
+
def generate_document(rdoc_document)
|
405
|
+
relative_path = (String === rdoc_document ? rdoc_document : rdoc_document.full_name)
|
406
|
+
absolute_path = File.join(path_base, relative_path)
|
407
|
+
|
408
|
+
model = Shomen::Model::Document.new
|
409
|
+
|
410
|
+
model.path = relative_path
|
411
|
+
model.name = File.basename(absolute_path)
|
412
|
+
model.mtime = File.mtime(absolute_path)
|
413
|
+
model.text = File.read(absolute_path) #file.comment
|
414
|
+
model.format = mime_type(absolute_path)
|
415
|
+
|
416
|
+
@table['/'+model.path] = model.to_h
|
417
|
+
end
|
418
|
+
|
419
|
+
# TODO: Add loadpath and make file path relative to it?
|
420
|
+
|
421
|
+
# Generate script entries.
|
422
|
+
#
|
423
|
+
# rdoc_file - RDoc file documentation object.
|
424
|
+
#
|
425
|
+
# Returns Hash of script entry.
|
426
|
+
def generate_script(rdoc_file)
|
427
|
+
#debug_msg "Generating file documentation in #{path_output_relative}:"
|
428
|
+
#templatefile = self.path_template + 'file.rhtml'
|
429
|
+
|
430
|
+
file = case rdoc_file
|
431
|
+
when String
|
432
|
+
rdoc_file
|
433
|
+
else
|
434
|
+
rdoc_file.full_name
|
435
|
+
end
|
436
|
+
|
437
|
+
debug_msg "%s" % [file]
|
438
|
+
|
439
|
+
absolute_path = File.join(path_base, file)
|
440
|
+
#rel_prefix = self.path_output.relative_path_from(outfile.dirname)
|
441
|
+
|
442
|
+
model = Shomen::Model::Script.new
|
443
|
+
|
444
|
+
model.path = file
|
445
|
+
model.name = File.basename(file)
|
446
|
+
model.mtime = File.mtime(absolute_path)
|
447
|
+
|
448
|
+
if source?
|
449
|
+
model.source = File.read(absolute_path)
|
450
|
+
model.language = mime_type(absolute_path)
|
451
|
+
end
|
452
|
+
|
453
|
+
webcvs = project_metadata['webcvs'] || webcvs
|
454
|
+
if webcvs
|
455
|
+
model.uri = File.join(webcvs, model.path)
|
456
|
+
model.language = mime_type(absolute_path)
|
457
|
+
end
|
458
|
+
|
459
|
+
# TODO: what use is rdoc_file.comment ?
|
460
|
+
#model.header =
|
461
|
+
#model.footer =
|
462
|
+
|
463
|
+
unless String === rdoc_file
|
464
|
+
model.requires = rdoc_file.requires.map{ |r| r.name }
|
465
|
+
model.constants = rdoc_file.constants.map{ |c| c.full_name }
|
466
|
+
end
|
467
|
+
|
468
|
+
# note that this utilizes the table we are building
|
469
|
+
# so it needs to be the last thing done.
|
470
|
+
@table.each do |k, h|
|
471
|
+
case h['!']
|
472
|
+
when 'module'
|
473
|
+
model.modules ||= []
|
474
|
+
model.modules << k if h['files'].include?(file)
|
475
|
+
when 'class'
|
476
|
+
model.classes ||= []
|
477
|
+
model.classes << k if h['files'].include?(file)
|
478
|
+
when 'method'
|
479
|
+
model.methods ||= []
|
480
|
+
model.methods << k if h['file'] == file
|
481
|
+
when 'class-method'
|
482
|
+
model.class_methods ||= []
|
483
|
+
model.class_methods << k if h['file'] == file
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
@table['/'+model.path] = model.to_h
|
488
|
+
end
|
489
|
+
|
490
|
+
# Get fully qualified name given +name+ and +namespace+.
|
491
|
+
#
|
492
|
+
# name - String of name.
|
493
|
+
# namespace - String of namespace.
|
494
|
+
#
|
495
|
+
# Returns String of fully qualified name.
|
496
|
+
def complete_name(name, namespace)
|
497
|
+
if name !~ /^#{namespace}/
|
498
|
+
"#{namespace}::#{name}"
|
499
|
+
else
|
500
|
+
name
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
# Get full method name.
|
505
|
+
#
|
506
|
+
# method - Method instance.
|
507
|
+
#
|
508
|
+
# Returns String of methods full name.
|
509
|
+
def method_name(method)
|
510
|
+
return nil if method.nil?
|
511
|
+
if method.singleton
|
512
|
+
i = method.full_name.rindex('::')
|
513
|
+
method.full_name[0...i] + '.' + method.full_name[i+2..-1]
|
514
|
+
else
|
515
|
+
method.full_name
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
# Convert rdoc object comment into RDoc text.
|
520
|
+
#
|
521
|
+
# document - RDoc document object.
|
522
|
+
#
|
523
|
+
# Returns String of comment text.
|
524
|
+
def comment(document)
|
525
|
+
formatter = RDoc::Markup::ToRdoc.new
|
526
|
+
text = document.accept(formatter)
|
527
|
+
text.strip
|
528
|
+
end
|
529
|
+
|
530
|
+
# Determine mime-type by file extension. If a type can not be determined,
|
531
|
+
# then returns `text/plain` type.
|
532
|
+
#
|
533
|
+
# path - String file path.
|
534
|
+
#
|
535
|
+
# Returns String of mime-type.
|
536
|
+
def mime_type(path)
|
537
|
+
case File.extname(path)
|
538
|
+
when '.rb', '.rbx' then 'text/ruby'
|
539
|
+
when '.c' then 'text/c-source'
|
540
|
+
when '.rdoc' then 'text/rdoc'
|
541
|
+
when '.md', '.markdown' then 'text/markdown'
|
542
|
+
else 'text/plain'
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
# Output progress information if rdoc debugging is enabled
|
547
|
+
#
|
548
|
+
# msg - String debug message.
|
549
|
+
#
|
550
|
+
# Returns nothing.
|
551
|
+
def debug_msg(msg)
|
552
|
+
return unless $DEBUG_RDOC
|
553
|
+
case msg[-1,1]
|
554
|
+
when '.' then tab = "= "
|
555
|
+
when ':' then tab = "== "
|
556
|
+
else tab = "* "
|
557
|
+
end
|
558
|
+
$stderr.puts(tab + msg)
|
559
|
+
end
|
560
|
+
|
561
|
+
# Current working directory.
|
562
|
+
#
|
563
|
+
# Returns String of working directory.
|
564
|
+
def path_base
|
565
|
+
Dir.pwd
|
566
|
+
end
|
567
|
+
|
568
|
+
end
|
569
|
+
|
570
|
+
end
|
571
|
+
|
572
|
+
end
|
573
|
+
|
574
|
+
|
575
|
+
|
576
|
+
|
577
|
+
|
578
|
+
|
579
|
+
=begin
|
580
|
+
|
581
|
+
require 'fileutils'
|
582
|
+
require 'pathname'
|
583
|
+
require 'yaml'
|
584
|
+
require 'json'
|
585
|
+
|
586
|
+
require 'rdoc/rdoc'
|
587
|
+
require 'rdoc/generator'
|
588
|
+
require 'rdoc/generator/markup'
|
589
|
+
|
590
|
+
require 'shomen/metadata'
|
591
|
+
require 'shomen/model' # TODO: have metadata in model
|
592
|
+
require 'shomen/rdoc/extensions'
|
593
|
+
|
594
|
+
# Shomen Adaptor for RDoc utilizes the rdoc tool to parse ruby source code
|
595
|
+
# to build a Shomen documenation file.
|
596
|
+
#
|
597
|
+
# RDoc is almost entirely a free-form documentation system, so it is not
|
598
|
+
# possible for Shomen to fully harness all the details it can support from
|
599
|
+
# the RDoc documentation, such as method argument descriptions.
|
600
|
+
|
601
|
+
class RDoc::Generator::Shomen
|
602
|
+
|
603
|
+
# Register shomen generator with RDoc.
|
604
|
+
RDoc::RDoc.add_generator(self)
|
605
|
+
|
606
|
+
#include RDocShomen::Metadata
|
607
|
+
|
608
|
+
# Standard generator factory method.
|
609
|
+
def self.for(options)
|
610
|
+
new(options)
|
611
|
+
end
|
612
|
+
|
613
|
+
# User options from the command line.
|
614
|
+
attr :options
|
615
|
+
|
616
|
+
# List of all classes and modules.
|
617
|
+
#def all_classes_and_modules
|
618
|
+
# @all_classes_and_modules ||= RDoc::TopLevel.all_classes_and_modules
|
619
|
+
#end
|
620
|
+
|
621
|
+
# In the world of the RDoc Generators #classes is the same
|
622
|
+
# as #all_classes_and_modules. Well, except that its sorted
|
623
|
+
# too. For classes sans modules, see #types.
|
624
|
+
|
625
|
+
def classes
|
626
|
+
@classes ||= RDoc::TopLevel.all_classes_and_modules.sort
|
627
|
+
end
|
628
|
+
|
629
|
+
# Only toplevel classes and modules.
|
630
|
+
def classes_toplevel
|
631
|
+
@classes_toplevel ||= classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
|
632
|
+
end
|
633
|
+
|
634
|
+
#
|
635
|
+
def files
|
636
|
+
@files ||= (
|
637
|
+
@files_rdoc.select{ |f| f.parser != RDoc::Parser::Simple }
|
638
|
+
)
|
639
|
+
end
|
640
|
+
|
641
|
+
# List of toplevel files. RDoc supplies this via the #generate method.
|
642
|
+
def files_toplevel
|
643
|
+
@files_toplevel ||= (
|
644
|
+
@files_rdoc.select{ |f| f.parser == RDoc::Parser::Simple }
|
645
|
+
)
|
646
|
+
end
|
647
|
+
|
648
|
+
#
|
649
|
+
|
650
|
+
def files_hash
|
651
|
+
@files ||= RDoc::TopLevel.files_hash
|
652
|
+
end
|
653
|
+
|
654
|
+
# List of all methods in all classes and modules.
|
655
|
+
def methods_all
|
656
|
+
@methods_all ||= classes.map{ |m| m.method_list }.flatten.sort
|
657
|
+
end
|
658
|
+
|
659
|
+
# List of all attributes in all classes and modules.
|
660
|
+
def attributes_all
|
661
|
+
@attributes_all ||= classes.map{ |m| m.attributes }.flatten.sort
|
662
|
+
end
|
663
|
+
|
664
|
+
#
|
665
|
+
def constants_all
|
666
|
+
@constants_all ||= classes.map{ |c| c.constants }.flatten
|
667
|
+
end
|
668
|
+
|
669
|
+
## TODO: What's this then?
|
670
|
+
##def json_creatable?
|
671
|
+
## RDoc::TopLevel.json_creatable?
|
672
|
+
##end
|
673
|
+
|
674
|
+
# RDoc needs this to function.
|
675
|
+
def class_dir ; nil ; end
|
676
|
+
|
677
|
+
# RDoc needs this to function.
|
678
|
+
def file_dir ; nil ; end
|
679
|
+
|
680
|
+
# TODO: Rename ?
|
681
|
+
def shomen
|
682
|
+
@table || {}
|
683
|
+
end
|
684
|
+
|
685
|
+
# Build the initial indices and output objects
|
686
|
+
# based on an array of top level objects containing
|
687
|
+
# the extracted information.
|
688
|
+
def generate(files)
|
689
|
+
@files_rdoc = files.sort
|
690
|
+
|
691
|
+
@table = {}
|
692
|
+
|
693
|
+
generate_metadata
|
694
|
+
generate_constants
|
695
|
+
generate_classes
|
696
|
+
#generate_attributes
|
697
|
+
generate_methods
|
698
|
+
generate_documents
|
699
|
+
generate_scripts # must be last b/c it depends on the others
|
700
|
+
|
701
|
+
# TODO: method accessor fields need to be handled
|
702
|
+
|
703
|
+
# THINK: Internal referencing model, YAML and JSYNC ?
|
704
|
+
#ref_table = reference_table(@table)
|
705
|
+
|
706
|
+
#rescue StandardError => err
|
707
|
+
# debug_msg "%s: %s\n %s" % [ err.class.name, err.message, err.backtrace.join("\n ") ]
|
708
|
+
# raise err
|
709
|
+
end
|
710
|
+
|
711
|
+
|
712
|
+
protected
|
713
|
+
|
714
|
+
#
|
715
|
+
def initialize(options)
|
716
|
+
@options = options
|
717
|
+
#@options.diagram = false # why?
|
718
|
+
|
719
|
+
@path_base = Pathname.pwd.expand_path
|
720
|
+
|
721
|
+
# TODO: This is probably not needed any more.
|
722
|
+
@path_output = Pathname.new(@options.op_dir).expand_path(@path_base)
|
723
|
+
end
|
724
|
+
|
725
|
+
# Current pathname.
|
726
|
+
attr :path_base
|
727
|
+
|
728
|
+
# The output path.
|
729
|
+
attr :path_output
|
730
|
+
|
731
|
+
#
|
732
|
+
def path_output_relative(path=nil)
|
733
|
+
if path
|
734
|
+
path.to_s.sub(path_base.to_s+'/', '')
|
735
|
+
else
|
736
|
+
@path_output_relative ||= path_output.to_s.sub(path_base.to_s+'/', '')
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
#
|
741
|
+
def collect_methods(class_module, singleton=false)
|
742
|
+
list = []
|
743
|
+
class_module.method_list.each do |m|
|
744
|
+
next if singleton ^ m.singleton
|
745
|
+
list << method_name(m)
|
746
|
+
end
|
747
|
+
list.uniq
|
748
|
+
end
|
749
|
+
|
750
|
+
#
|
751
|
+
def collect_attributes(class_module, singleton=false)
|
752
|
+
list = []
|
753
|
+
class_module.attributes.each do |a|
|
754
|
+
next if singleton ^ a.singleton
|
755
|
+
#p a.rw
|
756
|
+
#case a.rw
|
757
|
+
#when :write, 'W'
|
758
|
+
# list << "#{method_name(a)}="
|
759
|
+
#else
|
760
|
+
list << method_name(a)
|
761
|
+
#end
|
762
|
+
end
|
763
|
+
list.uniq
|
764
|
+
end
|
765
|
+
|
766
|
+
=end
|
767
|
+
|
768
|
+
|
769
|
+
|
770
|
+
#--
|
771
|
+
=begin
|
772
|
+
#
|
773
|
+
def generate_attributes
|
774
|
+
#$stderr.puts "HERE!"
|
775
|
+
#$stderr.puts attributes_all.inspect
|
776
|
+
#exit
|
777
|
+
debug_msg "Generating attributes documentation:"
|
778
|
+
attributes_all.each do |rdoc_attribute|
|
779
|
+
debug_msg "%s" % [rdoc_attribute.full_name]
|
780
|
+
|
781
|
+
adapter = Shomen::RDoc::MethodAdapter.new(rdoc_attribute)
|
782
|
+
data = Shomen::Model::Method.new(adapter).to_h
|
783
|
+
|
784
|
+
@table[data['path']] = data
|
785
|
+
|
786
|
+
#code = m.source_code_raw
|
787
|
+
#file, line = m.source_code_location
|
788
|
+
|
789
|
+
#full_name = method_name(m)
|
790
|
+
|
791
|
+
#'prettyname' => m.pretty_name,
|
792
|
+
#'type' => m.type, # class or instance
|
793
|
+
|
794
|
+
#model_class = m.singleton ? Shomen::Model::Function : Shomen::Model::Method
|
795
|
+
#model_class = Shomen::Model::Attribute
|
796
|
+
|
797
|
+
#@table[full_name] = model_class.new(
|
798
|
+
# 'path' => full_name,
|
799
|
+
# 'name' => m.name,
|
800
|
+
# 'namespace' => m.parent_name,
|
801
|
+
# 'comment' => m.comment.text,
|
802
|
+
# 'access' => m.visibility.to_s,
|
803
|
+
# 'rw' => m.rw, # TODO: better name ?
|
804
|
+
# 'singleton' => m.singleton,
|
805
|
+
# 'aliases' => m.aliases.map{ |a| method_name(a) },
|
806
|
+
# 'alias_for' => method_name(m.is_alias_for),
|
807
|
+
# 'image' => m.params,
|
808
|
+
# 'arguments' => [],
|
809
|
+
# 'parameters' => [],
|
810
|
+
# 'block' => m.block_params, # TODO: what is block?
|
811
|
+
# 'interface' => m.arglists,
|
812
|
+
# 'returns' => [],
|
813
|
+
# 'file' => file,
|
814
|
+
# 'line' => line,
|
815
|
+
# 'source' => code
|
816
|
+
#).to_h
|
817
|
+
end
|
818
|
+
end
|
819
|
+
=end
|
820
|
+
#++
|
821
|
+
|
822
|
+
|
823
|
+
#--
|
824
|
+
=begin
|
825
|
+
#
|
826
|
+
# N O T U S E D
|
827
|
+
#
|
828
|
+
|
829
|
+
# Sort based on how often the top level namespace occurs, and then on the
|
830
|
+
# name of the module -- this works for projects that put their stuff into
|
831
|
+
# a namespace, of course, but doesn't hurt if they don't.
|
832
|
+
def sort_salient(classes)
|
833
|
+
nscounts = classes.inject({}) do |counthash, klass|
|
834
|
+
top_level = klass.full_name.gsub( /::.*/, '' )
|
835
|
+
counthash[top_level] ||= 0
|
836
|
+
counthash[top_level] += 1
|
837
|
+
counthash
|
838
|
+
endfiles_toplevel
|
839
|
+
classes.sort_by{ |klass|
|
840
|
+
top_level = klass.full_name.gsub( /::.*/, '' )
|
841
|
+
[nscounts[top_level] * -1, klass.full_name]
|
842
|
+
}.select{ |klass|
|
843
|
+
klass.document_self
|
844
|
+
}
|
845
|
+
end
|
846
|
+
=end
|
847
|
+
|
848
|
+
=begin
|
849
|
+
# Loop through table and convert all named references into bonofied object
|
850
|
+
# references.
|
851
|
+
def reference_table(table)
|
852
|
+
debug_msg "== Generating Reference Table"
|
853
|
+
new_table = {}
|
854
|
+
table.each do |key, entry|
|
855
|
+
debug_msg "%s" % [key]
|
856
|
+
data = entry.dup
|
857
|
+
new_table[key] = data
|
858
|
+
case data['!']
|
859
|
+
when 'script'
|
860
|
+
data["constants"] = ref_list(data["constants"])
|
861
|
+
data["modules"] = ref_list(data["modules"])
|
862
|
+
data["classes"] = ref_list(data["classes"])
|
863
|
+
data["functions"] = ref_list(data["functions"])
|
864
|
+
data["methods"] = ref_list(data["methods"])
|
865
|
+
when 'file'
|
866
|
+
when 'constant'
|
867
|
+
data["namespace"] = ref_item(data["namespace"])
|
868
|
+
when 'module', 'class'
|
869
|
+
data["namespace"] = ref_item(data["namespace"])
|
870
|
+
data["includes"] = ref_list(data["includes"])
|
871
|
+
#data["extended"] = ref_list(data["extended"])
|
872
|
+
data["constants"] = ref_list(data["constants"])
|
873
|
+
data["modules"] = ref_list(data["modules"])
|
874
|
+
data["classes"] = ref_list(data["classes"])
|
875
|
+
data["functions"] = ref_list(data["functions"])
|
876
|
+
data["methods"] = ref_list(data["methods"])
|
877
|
+
data["files"] = ref_list(data["files"])
|
878
|
+
data["superclass"] = ref_item(data["superclass"]) if data.key?("superclass")
|
879
|
+
when 'method', 'function'
|
880
|
+
data["namespace"] = ref_item(data["namespace"])
|
881
|
+
data["file"] = ref_item(data["file"])
|
882
|
+
end
|
883
|
+
end
|
884
|
+
new_table
|
885
|
+
end
|
886
|
+
|
887
|
+
# Given a key, return the matching table item. If not found return the key.
|
888
|
+
def ref_item(key)
|
889
|
+
@table[key] || key
|
890
|
+
end
|
891
|
+
|
892
|
+
# Given a list of keys, return the matching table items.
|
893
|
+
def ref_list(keys)
|
894
|
+
#keys.map{ |k| @table[k] || k }
|
895
|
+
keys.map{ |k| @table[k] || nil }.compact
|
896
|
+
end
|
897
|
+
|
898
|
+
=end
|
899
|
+
#++
|
900
|
+
|