rdoc-f95 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +79 -0
  3. data/PostInstall.txt +7 -0
  4. data/README.rdoc +147 -0
  5. data/Rakefile +28 -0
  6. data/bin/rdoc-f95 +70 -0
  7. data/lib/rdoc-f95.rb +306 -0
  8. data/lib/rdoc-f95/code_objects.rb +776 -0
  9. data/lib/rdoc-f95/diagram.rb +342 -0
  10. data/lib/rdoc-f95/dot.rb +249 -0
  11. data/lib/rdoc-f95/generator.rb +1088 -0
  12. data/lib/rdoc-f95/generator/chm.rb +113 -0
  13. data/lib/rdoc-f95/generator/chm/chm.rb +98 -0
  14. data/lib/rdoc-f95/generator/html.rb +370 -0
  15. data/lib/rdoc-f95/generator/html/hefss.rb +414 -0
  16. data/lib/rdoc-f95/generator/html/html.rb +708 -0
  17. data/lib/rdoc-f95/generator/html/kilmer.rb +418 -0
  18. data/lib/rdoc-f95/generator/html/one_page_html.rb +121 -0
  19. data/lib/rdoc-f95/generator/ri.rb +229 -0
  20. data/lib/rdoc-f95/generator/xhtml.rb +106 -0
  21. data/lib/rdoc-f95/generator/xhtml/ctop.xsl +1318 -0
  22. data/lib/rdoc-f95/generator/xhtml/mathml.xsl +42 -0
  23. data/lib/rdoc-f95/generator/xhtml/pmathml.xsl +612 -0
  24. data/lib/rdoc-f95/generator/xhtml/pmathmlcss.xsl +872 -0
  25. data/lib/rdoc-f95/generator/xhtml/xhtml.rb +732 -0
  26. data/lib/rdoc-f95/generator/xml.rb +120 -0
  27. data/lib/rdoc-f95/generator/xml/rdf.rb +113 -0
  28. data/lib/rdoc-f95/generator/xml/xml.rb +111 -0
  29. data/lib/rdoc-f95/install.rb +166 -0
  30. data/lib/rdoc-f95/markup.rb +506 -0
  31. data/lib/rdoc-f95/markup/formatter.rb +14 -0
  32. data/lib/rdoc-f95/markup/fragments.rb +337 -0
  33. data/lib/rdoc-f95/markup/inline.rb +361 -0
  34. data/lib/rdoc-f95/markup/install.rb +57 -0
  35. data/lib/rdoc-f95/markup/lines.rb +152 -0
  36. data/lib/rdoc-f95/markup/mathml_wrapper.rb +91 -0
  37. data/lib/rdoc-f95/markup/preprocess.rb +71 -0
  38. data/lib/rdoc-f95/markup/sample/rdoc2latex.rb +16 -0
  39. data/lib/rdoc-f95/markup/sample/sample.rb +42 -0
  40. data/lib/rdoc-f95/markup/to_flow.rb +185 -0
  41. data/lib/rdoc-f95/markup/to_html.rb +357 -0
  42. data/lib/rdoc-f95/markup/to_html_crossref.rb +123 -0
  43. data/lib/rdoc-f95/markup/to_latex.rb +328 -0
  44. data/lib/rdoc-f95/markup/to_test.rb +50 -0
  45. data/lib/rdoc-f95/markup/to_xhtml_texparser.rb +234 -0
  46. data/lib/rdoc-f95/options.rb +745 -0
  47. data/lib/rdoc-f95/parsers/parse_c.rb +775 -0
  48. data/lib/rdoc-f95/parsers/parse_f95.rb +2499 -0
  49. data/lib/rdoc-f95/parsers/parse_rb.rb +2587 -0
  50. data/lib/rdoc-f95/parsers/parse_simple.rb +39 -0
  51. data/lib/rdoc-f95/parsers/parserfactory.rb +99 -0
  52. data/lib/rdoc-f95/ri.rb +2 -0
  53. data/lib/rdoc-f95/ri/cache.rb +188 -0
  54. data/lib/rdoc-f95/ri/descriptions.rb +147 -0
  55. data/lib/rdoc-f95/ri/display.rb +244 -0
  56. data/lib/rdoc-f95/ri/driver.rb +435 -0
  57. data/lib/rdoc-f95/ri/formatter.rb +603 -0
  58. data/lib/rdoc-f95/ri/paths.rb +105 -0
  59. data/lib/rdoc-f95/ri/reader.rb +106 -0
  60. data/lib/rdoc-f95/ri/util.rb +81 -0
  61. data/lib/rdoc-f95/ri/writer.rb +64 -0
  62. data/lib/rdoc-f95/stats.rb +23 -0
  63. data/lib/rdoc-f95/template.rb +64 -0
  64. data/lib/rdoc-f95/tokenstream.rb +33 -0
  65. data/lib/rdoc-f95/usage.rb +210 -0
  66. data/script/console +10 -0
  67. data/script/destroy +14 -0
  68. data/script/generate +14 -0
  69. data/test/test_helper.rb +3 -0
  70. data/test/test_rdoc-f95.rb +11 -0
  71. 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
@@ -0,0 +1,2 @@
1
+ module RDocF95::RI; end
2
+
@@ -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
+