rdoc-f95 0.0.1
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/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
|
+
|