rdoc-f95 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +79 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +147 -0
- data/Rakefile +28 -0
- data/bin/rdoc-f95 +70 -0
- data/lib/rdoc-f95.rb +306 -0
- data/lib/rdoc-f95/code_objects.rb +776 -0
- data/lib/rdoc-f95/diagram.rb +342 -0
- data/lib/rdoc-f95/dot.rb +249 -0
- data/lib/rdoc-f95/generator.rb +1088 -0
- data/lib/rdoc-f95/generator/chm.rb +113 -0
- data/lib/rdoc-f95/generator/chm/chm.rb +98 -0
- data/lib/rdoc-f95/generator/html.rb +370 -0
- data/lib/rdoc-f95/generator/html/hefss.rb +414 -0
- data/lib/rdoc-f95/generator/html/html.rb +708 -0
- data/lib/rdoc-f95/generator/html/kilmer.rb +418 -0
- data/lib/rdoc-f95/generator/html/one_page_html.rb +121 -0
- data/lib/rdoc-f95/generator/ri.rb +229 -0
- data/lib/rdoc-f95/generator/xhtml.rb +106 -0
- data/lib/rdoc-f95/generator/xhtml/ctop.xsl +1318 -0
- data/lib/rdoc-f95/generator/xhtml/mathml.xsl +42 -0
- data/lib/rdoc-f95/generator/xhtml/pmathml.xsl +612 -0
- data/lib/rdoc-f95/generator/xhtml/pmathmlcss.xsl +872 -0
- data/lib/rdoc-f95/generator/xhtml/xhtml.rb +732 -0
- data/lib/rdoc-f95/generator/xml.rb +120 -0
- data/lib/rdoc-f95/generator/xml/rdf.rb +113 -0
- data/lib/rdoc-f95/generator/xml/xml.rb +111 -0
- data/lib/rdoc-f95/install.rb +166 -0
- data/lib/rdoc-f95/markup.rb +506 -0
- data/lib/rdoc-f95/markup/formatter.rb +14 -0
- data/lib/rdoc-f95/markup/fragments.rb +337 -0
- data/lib/rdoc-f95/markup/inline.rb +361 -0
- data/lib/rdoc-f95/markup/install.rb +57 -0
- data/lib/rdoc-f95/markup/lines.rb +152 -0
- data/lib/rdoc-f95/markup/mathml_wrapper.rb +91 -0
- data/lib/rdoc-f95/markup/preprocess.rb +71 -0
- data/lib/rdoc-f95/markup/sample/rdoc2latex.rb +16 -0
- data/lib/rdoc-f95/markup/sample/sample.rb +42 -0
- data/lib/rdoc-f95/markup/to_flow.rb +185 -0
- data/lib/rdoc-f95/markup/to_html.rb +357 -0
- data/lib/rdoc-f95/markup/to_html_crossref.rb +123 -0
- data/lib/rdoc-f95/markup/to_latex.rb +328 -0
- data/lib/rdoc-f95/markup/to_test.rb +50 -0
- data/lib/rdoc-f95/markup/to_xhtml_texparser.rb +234 -0
- data/lib/rdoc-f95/options.rb +745 -0
- data/lib/rdoc-f95/parsers/parse_c.rb +775 -0
- data/lib/rdoc-f95/parsers/parse_f95.rb +2499 -0
- data/lib/rdoc-f95/parsers/parse_rb.rb +2587 -0
- data/lib/rdoc-f95/parsers/parse_simple.rb +39 -0
- data/lib/rdoc-f95/parsers/parserfactory.rb +99 -0
- data/lib/rdoc-f95/ri.rb +2 -0
- data/lib/rdoc-f95/ri/cache.rb +188 -0
- data/lib/rdoc-f95/ri/descriptions.rb +147 -0
- data/lib/rdoc-f95/ri/display.rb +244 -0
- data/lib/rdoc-f95/ri/driver.rb +435 -0
- data/lib/rdoc-f95/ri/formatter.rb +603 -0
- data/lib/rdoc-f95/ri/paths.rb +105 -0
- data/lib/rdoc-f95/ri/reader.rb +106 -0
- data/lib/rdoc-f95/ri/util.rb +81 -0
- data/lib/rdoc-f95/ri/writer.rb +64 -0
- data/lib/rdoc-f95/stats.rb +23 -0
- data/lib/rdoc-f95/template.rb +64 -0
- data/lib/rdoc-f95/tokenstream.rb +33 -0
- data/lib/rdoc-f95/usage.rb +210 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test/test_helper.rb +3 -0
- data/test/test_rdoc-f95.rb +11 -0
- metadata +156 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rdoc-f95/code_objects'
|
2
|
+
require 'rdoc-f95/markup/preprocess'
|
3
|
+
|
4
|
+
##
|
5
|
+
# Parse a non-source file. We basically take the whole thing as one big
|
6
|
+
# comment. If the first character in the file is '#', we strip leading pound
|
7
|
+
# signs.
|
8
|
+
|
9
|
+
class RDocF95::SimpleParser
|
10
|
+
|
11
|
+
##
|
12
|
+
# Prepare to parse a plain file
|
13
|
+
|
14
|
+
def initialize(top_level, file_name, body, options, stats)
|
15
|
+
preprocess = RDocF95::Markup::PreProcess.new(file_name, options.rdoc_include)
|
16
|
+
|
17
|
+
preprocess.handle(body) do |directive, param|
|
18
|
+
warn "Unrecognized directive '#{directive}' in #{file_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
@body = body
|
22
|
+
@options = options
|
23
|
+
@top_level = top_level
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Extract the file contents and attach them to the toplevel as a comment
|
28
|
+
|
29
|
+
def scan
|
30
|
+
@top_level.comment = remove_private_comments(@body)
|
31
|
+
@top_level
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_private_comments(comment)
|
35
|
+
comment.gsub(/^--[^-].*?^\+\+/m, '').sub(/^--.*/m, '')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require "rdoc-f95/parsers/parse_simple"
|
2
|
+
|
3
|
+
module RDocF95
|
4
|
+
|
5
|
+
# A parser is simple a class that implements
|
6
|
+
#
|
7
|
+
# #initialize(file_name, body, options)
|
8
|
+
#
|
9
|
+
# and
|
10
|
+
#
|
11
|
+
# #scan
|
12
|
+
#
|
13
|
+
# The initialize method takes a file name to be used, the body of the
|
14
|
+
# file, and an RDocF95::Options object. The scan method is then called
|
15
|
+
# to return an appropriately parsed TopLevel code object.
|
16
|
+
#
|
17
|
+
# The ParseFactory is used to redirect to the correct parser given a filename
|
18
|
+
# extension. This magic works because individual parsers have to register
|
19
|
+
# themselves with us as they are loaded in. The do this using the following
|
20
|
+
# incantation
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# require "rdoc-f95/parsers/parsefactory"
|
24
|
+
#
|
25
|
+
# module RDocF95
|
26
|
+
#
|
27
|
+
# class XyzParser
|
28
|
+
# extend ParseFactory <<<<
|
29
|
+
# parse_files_matching /\.xyz$/ <<<<
|
30
|
+
#
|
31
|
+
# def initialize(file_name, body, options)
|
32
|
+
# ...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def scan
|
36
|
+
# ...
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# Just to make life interesting, if we suspect a plain text file, we
|
42
|
+
# also look for a shebang line just in case it's a potential
|
43
|
+
# shell script
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
module ParserFactory
|
48
|
+
|
49
|
+
@@parsers = []
|
50
|
+
|
51
|
+
Parsers = Struct.new(:regexp, :parser)
|
52
|
+
|
53
|
+
# Record the fact that a particular class parses files that
|
54
|
+
# match a given extension
|
55
|
+
|
56
|
+
def parse_files_matching(regexp)
|
57
|
+
@@parsers.unshift Parsers.new(regexp, self)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Return a parser that can handle a particular extension
|
61
|
+
|
62
|
+
def ParserFactory.can_parse(file_name)
|
63
|
+
@@parsers.find {|p| p.regexp.match(file_name) }
|
64
|
+
end
|
65
|
+
|
66
|
+
# Alias an extension to another extension. After this call,
|
67
|
+
# files ending "new_ext" will be parsed using the same parser
|
68
|
+
# as "old_ext"
|
69
|
+
|
70
|
+
def ParserFactory.alias_extension(old_ext, new_ext)
|
71
|
+
parser = ParserFactory.can_parse("xxx.#{old_ext}")
|
72
|
+
return false unless parser
|
73
|
+
@@parsers.unshift Parsers.new(Regexp.new("\\.#{new_ext}$"), parser.parser)
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
# Find the correct parser for a particular file name. Return a
|
78
|
+
# SimpleParser for ones that we don't know
|
79
|
+
|
80
|
+
def ParserFactory.parser_for(top_level, file_name, body, options, stats)
|
81
|
+
# If no extension, look for shebang
|
82
|
+
if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)}
|
83
|
+
shebang = $1
|
84
|
+
case shebang
|
85
|
+
when %r{env\s+ruby}, %r{/ruby}
|
86
|
+
file_name = "dummy.rb"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
parser_description = can_parse(file_name)
|
90
|
+
if parser_description
|
91
|
+
parser = parser_description.parser
|
92
|
+
else
|
93
|
+
parser = SimpleParser
|
94
|
+
end
|
95
|
+
|
96
|
+
parser.new(top_level, file_name, body, options, stats)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/rdoc-f95/ri.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'rdoc-f95/ri'
|
2
|
+
|
3
|
+
class RDocF95::RI::ClassEntry
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
attr_reader :path_names
|
7
|
+
|
8
|
+
def initialize(path_name, name, in_class)
|
9
|
+
@path_names = [ path_name ]
|
10
|
+
@name = name
|
11
|
+
@in_class = in_class
|
12
|
+
@class_methods = []
|
13
|
+
@instance_methods = []
|
14
|
+
@inferior_classes = []
|
15
|
+
end
|
16
|
+
|
17
|
+
# We found this class in more tha one place, so add
|
18
|
+
# in the name from there.
|
19
|
+
def add_path(path)
|
20
|
+
@path_names << path
|
21
|
+
end
|
22
|
+
|
23
|
+
# read in our methods and any classes
|
24
|
+
# and modules in our namespace. Methods are
|
25
|
+
# stored in files called name-c|i.yaml,
|
26
|
+
# where the 'name' portion is the external
|
27
|
+
# form of the method name and the c|i is a class|instance
|
28
|
+
# flag
|
29
|
+
|
30
|
+
def load_from(dir)
|
31
|
+
Dir.foreach(dir) do |name|
|
32
|
+
next if name =~ /^\./
|
33
|
+
|
34
|
+
# convert from external to internal form, and
|
35
|
+
# extract the instance/class flag
|
36
|
+
|
37
|
+
if name =~ /^(.*?)-(c|i).yaml$/
|
38
|
+
external_name = $1
|
39
|
+
is_class_method = $2 == "c"
|
40
|
+
internal_name = RiWriter.external_to_internal(external_name)
|
41
|
+
list = is_class_method ? @class_methods : @instance_methods
|
42
|
+
path = File.join(dir, name)
|
43
|
+
list << MethodEntry.new(path, internal_name, is_class_method, self)
|
44
|
+
else
|
45
|
+
full_name = File.join(dir, name)
|
46
|
+
if File.directory?(full_name)
|
47
|
+
inf_class = @inferior_classes.find {|c| c.name == name }
|
48
|
+
if inf_class
|
49
|
+
inf_class.add_path(full_name)
|
50
|
+
else
|
51
|
+
inf_class = ClassEntry.new(full_name, name, self)
|
52
|
+
@inferior_classes << inf_class
|
53
|
+
end
|
54
|
+
inf_class.load_from(full_name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Return a list of any classes or modules that we contain
|
61
|
+
# that match a given string
|
62
|
+
|
63
|
+
def contained_modules_matching(name)
|
64
|
+
@inferior_classes.find_all {|c| c.name[name]}
|
65
|
+
end
|
66
|
+
|
67
|
+
def classes_and_modules
|
68
|
+
@inferior_classes
|
69
|
+
end
|
70
|
+
|
71
|
+
# Return an exact match to a particular name
|
72
|
+
def contained_class_named(name)
|
73
|
+
@inferior_classes.find {|c| c.name == name}
|
74
|
+
end
|
75
|
+
|
76
|
+
# return the list of local methods matching name
|
77
|
+
# We're split into two because we need distinct behavior
|
78
|
+
# when called from the _toplevel_
|
79
|
+
def methods_matching(name, is_class_method)
|
80
|
+
local_methods_matching(name, is_class_method)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Find methods matching 'name' in ourselves and in
|
84
|
+
# any classes we contain
|
85
|
+
def recursively_find_methods_matching(name, is_class_method)
|
86
|
+
res = local_methods_matching(name, is_class_method)
|
87
|
+
@inferior_classes.each do |c|
|
88
|
+
res.concat(c.recursively_find_methods_matching(name, is_class_method))
|
89
|
+
end
|
90
|
+
res
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# Return our full name
|
95
|
+
def full_name
|
96
|
+
res = @in_class.full_name
|
97
|
+
res << "::" unless res.empty?
|
98
|
+
res << @name
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return a list of all out method names
|
102
|
+
def all_method_names
|
103
|
+
res = @class_methods.map {|m| m.full_name }
|
104
|
+
@instance_methods.each {|m| res << m.full_name}
|
105
|
+
res
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
# Return a list of all our methods matching a given string.
|
111
|
+
# Is +is_class_methods+ if 'nil', we don't care if the method
|
112
|
+
# is a class method or not, otherwise we only return
|
113
|
+
# those methods that match
|
114
|
+
def local_methods_matching(name, is_class_method)
|
115
|
+
|
116
|
+
list = case is_class_method
|
117
|
+
when nil then @class_methods + @instance_methods
|
118
|
+
when true then @class_methods
|
119
|
+
when false then @instance_methods
|
120
|
+
else fail "Unknown is_class_method: #{is_class_method.inspect}"
|
121
|
+
end
|
122
|
+
|
123
|
+
list.find_all {|m| m.name; m.name[name]}
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# A TopLevelEntry is like a class entry, but when asked to search for methods
|
129
|
+
# searches all classes, not just itself
|
130
|
+
|
131
|
+
class RDocF95::RI::TopLevelEntry < RDocF95::RI::ClassEntry
|
132
|
+
def methods_matching(name, is_class_method)
|
133
|
+
res = recursively_find_methods_matching(name, is_class_method)
|
134
|
+
end
|
135
|
+
|
136
|
+
def full_name
|
137
|
+
""
|
138
|
+
end
|
139
|
+
|
140
|
+
def module_named(name)
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
class RDocF95::RI::MethodEntry
|
147
|
+
attr_reader :name
|
148
|
+
attr_reader :path_name
|
149
|
+
|
150
|
+
def initialize(path_name, name, is_class_method, in_class)
|
151
|
+
@path_name = path_name
|
152
|
+
@name = name
|
153
|
+
@is_class_method = is_class_method
|
154
|
+
@in_class = in_class
|
155
|
+
end
|
156
|
+
|
157
|
+
def full_name
|
158
|
+
res = @in_class.full_name
|
159
|
+
unless res.empty?
|
160
|
+
if @is_class_method
|
161
|
+
res << "::"
|
162
|
+
else
|
163
|
+
res << "#"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
res << @name
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# We represent everything know about all 'ri' files accessible to this program
|
172
|
+
|
173
|
+
class RDocF95::RI::Cache
|
174
|
+
|
175
|
+
attr_reader :toplevel
|
176
|
+
|
177
|
+
def initialize(dirs)
|
178
|
+
# At the top level we have a dummy module holding the
|
179
|
+
# overall namespace
|
180
|
+
@toplevel = RDocF95::RI::TopLevelEntry.new('', '::', nil)
|
181
|
+
|
182
|
+
dirs.each do |dir|
|
183
|
+
@toplevel.load_from(dir)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rdoc-f95/markup/fragments'
|
3
|
+
require 'rdoc-f95/ri'
|
4
|
+
|
5
|
+
#--
|
6
|
+
# Descriptions are created by RDoc (in ri_generator) and written out in
|
7
|
+
# serialized form into the documentation tree. ri then reads these to generate
|
8
|
+
# the documentation
|
9
|
+
#++
|
10
|
+
|
11
|
+
class RDocF95::RI::RDocF95::RI::NamedThing
|
12
|
+
attr_reader :name
|
13
|
+
def initialize(name)
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
def <=>(other)
|
17
|
+
@name <=> other.name
|
18
|
+
end
|
19
|
+
|
20
|
+
def hash
|
21
|
+
@name.hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def eql?(other)
|
25
|
+
@name.eql?(other)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class RDocF95::RI::AliasName < RDocF95::RI::RDocF95::RI::NamedThing; end
|
30
|
+
|
31
|
+
class RDocF95::RI::Attribute < RDocF95::RI::RDocF95::RI::NamedThing
|
32
|
+
attr_reader :rw, :comment
|
33
|
+
def initialize(name, rw, comment)
|
34
|
+
super(name)
|
35
|
+
@rw = rw
|
36
|
+
@comment = comment
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class RDocF95::RI::Constant < RDocF95::RI::NamedThing
|
41
|
+
attr_reader :value, :comment
|
42
|
+
def initialize(name, value, comment)
|
43
|
+
super(name)
|
44
|
+
@value = value
|
45
|
+
@comment = comment
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class RDocF95::RI::IncludedModule < RDocF95::RI::NamedThing; end
|
50
|
+
|
51
|
+
class RDocF95::RI::MethodSummary < RDocF95::RI::NamedThing
|
52
|
+
def initialize(name="")
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class RDocF95::RI::Description
|
58
|
+
attr_accessor :name
|
59
|
+
attr_accessor :full_name
|
60
|
+
attr_accessor :comment
|
61
|
+
|
62
|
+
def serialize
|
63
|
+
self.to_yaml
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.deserialize(from)
|
67
|
+
YAML.load(from)
|
68
|
+
end
|
69
|
+
|
70
|
+
def <=>(other)
|
71
|
+
@name <=> other.name
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class RDocF95::RI::ModuleDescription < RDocF95::RI::Description
|
76
|
+
|
77
|
+
attr_accessor :class_methods
|
78
|
+
attr_accessor :instance_methods
|
79
|
+
attr_accessor :attributes
|
80
|
+
attr_accessor :constants
|
81
|
+
attr_accessor :includes
|
82
|
+
|
83
|
+
# merge in another class desscription into this one
|
84
|
+
def merge_in(old)
|
85
|
+
merge(@class_methods, old.class_methods)
|
86
|
+
merge(@instance_methods, old.instance_methods)
|
87
|
+
merge(@attributes, old.attributes)
|
88
|
+
merge(@constants, old.constants)
|
89
|
+
merge(@includes, old.includes)
|
90
|
+
if @comment.nil? || @comment.empty?
|
91
|
+
@comment = old.comment
|
92
|
+
else
|
93
|
+
unless old.comment.nil? or old.comment.empty? then
|
94
|
+
@comment << RDocF95::Markup::Flow::RULE.new
|
95
|
+
@comment.concat old.comment
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def display_name
|
101
|
+
"Module"
|
102
|
+
end
|
103
|
+
|
104
|
+
# the 'ClassDescription' subclass overrides this
|
105
|
+
# to format up the name of a parent
|
106
|
+
def superclass_string
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def merge(into, from)
|
113
|
+
names = {}
|
114
|
+
into.each {|i| names[i.name] = i }
|
115
|
+
from.each {|i| names[i.name] = i }
|
116
|
+
into.replace(names.keys.sort.map {|n| names[n]})
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class RDocF95::RI::ClassDescription < RDocF95::RI::ModuleDescription
|
121
|
+
attr_accessor :superclass
|
122
|
+
|
123
|
+
def display_name
|
124
|
+
"Class"
|
125
|
+
end
|
126
|
+
|
127
|
+
def superclass_string
|
128
|
+
if @superclass && @superclass != "Object"
|
129
|
+
@superclass
|
130
|
+
else
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class RDocF95::RI::MethodDescription < RDocF95::RI::Description
|
137
|
+
|
138
|
+
attr_accessor :is_class_method
|
139
|
+
attr_accessor :visibility
|
140
|
+
attr_accessor :block_params
|
141
|
+
attr_accessor :is_singleton
|
142
|
+
attr_accessor :aliases
|
143
|
+
attr_accessor :is_alias_for
|
144
|
+
attr_accessor :params
|
145
|
+
|
146
|
+
end
|
147
|
+
|