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,357 @@
1
+ require 'rdoc-f95/markup/formatter'
2
+ require 'rdoc-f95/markup/fragments'
3
+ require 'rdoc-f95/markup/inline'
4
+ require 'rdoc-f95/generator'
5
+
6
+ require 'cgi'
7
+
8
+ class RDocF95::Markup::ToHtml < RDocF95::Markup::Formatter
9
+
10
+ LIST_TYPE_TO_HTML = {
11
+ :BULLET => %w[<ul> </ul>],
12
+ :NUMBER => %w[<ol> </ol>],
13
+ :UPPERALPHA => %w[<ol> </ol>],
14
+ :LOWERALPHA => %w[<ol> </ol>],
15
+ :LABELED => %w[<dl> </dl>],
16
+ :NOTE => %w[<table> </table>],
17
+ }
18
+
19
+ InlineTag = Struct.new(:bit, :on, :off)
20
+
21
+ def initialize
22
+ super
23
+
24
+ # external hyperlinks
25
+ @markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
26
+
27
+ # and links of the form <text>[<url>]
28
+ @markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\.\S+?\])/, :TIDYLINK)
29
+
30
+ init_tags
31
+ end
32
+
33
+ ##
34
+ # Generate a hyperlink for url, labeled with text. Handle the
35
+ # special cases for img: and link: described under handle_special_HYPEDLINK
36
+
37
+ def gen_url(url, text)
38
+ if url =~ /([A-Za-z]+):(.*)/ then
39
+ type = $1
40
+ path = $2
41
+ else
42
+ type = "http"
43
+ path = url
44
+ url = "http://#{url}"
45
+ end
46
+
47
+ if type == "link" then
48
+ url = if path[0, 1] == '#' then # is this meaningful?
49
+ path
50
+ else
51
+ RDocF95::Generator.gen_url @from_path, path
52
+ end
53
+ end
54
+
55
+ if (type == "http" or type == "link") and
56
+ url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
57
+ "<img src=\"#{url}\" />"
58
+
59
+ elsif type == "link"
60
+ "<a href=\"#{url}\">#{text.sub(%r{^#{type}:/*}, '')}</a>"
61
+ else
62
+ "<a href=\"#{url}\" target=\"_top\">#{text.sub(%r{^#{type}:/*}, '')}</a>"
63
+ end
64
+ end
65
+
66
+ ##
67
+ # And we're invoked with a potential external hyperlink mailto:
68
+ # just gets inserted. http: links are checked to see if they
69
+ # reference an image. If so, that image gets inserted using an
70
+ # <img> tag. Otherwise a conventional <a href> is used. We also
71
+ # support a special type of hyperlink, link:, which is a reference
72
+ # to a local file whose path is relative to the --op directory.
73
+
74
+ def handle_special_HYPERLINK(special)
75
+ url = special.text
76
+ gen_url url, url
77
+ end
78
+
79
+ ##
80
+ # Here's a hypedlink where the label is different to the URL
81
+ # <label>[url] or {long label}[url]
82
+
83
+ def handle_special_TIDYLINK(special)
84
+ text = special.text
85
+
86
+ return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
87
+
88
+ label = $1
89
+ url = $2
90
+ gen_url url, label
91
+ end
92
+
93
+ ##
94
+ # Set up the standard mapping of attributes to HTML tags
95
+
96
+ def init_tags
97
+ @attr_tags = [
98
+ InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
99
+ InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(:TT), "<tt>", "</tt>"),
100
+ InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(:EM), "<em>", "</em>"),
101
+ ]
102
+ end
103
+
104
+ ##
105
+ # Add a new set of HTML tags for an attribute. We allow separate start and
106
+ # end tags for flexibility.
107
+
108
+ def add_tag(name, start, stop)
109
+ @attr_tags << InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(name), start, stop)
110
+ end
111
+
112
+ ##
113
+ # Given an HTML tag, decorate it with class information and the like if
114
+ # required. This is a no-op in the base class, but is overridden in HTML
115
+ # output classes that implement style sheets.
116
+
117
+ def annotate(tag)
118
+ tag
119
+ end
120
+
121
+ ##
122
+ # Here's the client side of the visitor pattern
123
+
124
+ def start_accepting
125
+ @res = ""
126
+ @in_list_entry = []
127
+ end
128
+
129
+ def end_accepting
130
+ @res
131
+ end
132
+
133
+ def accept_paragraph(am, fragment)
134
+ @res << annotate("<p>") + "\n"
135
+ @res << wrap(convert_flow(am.flow(fragment.txt)))
136
+ @res << annotate("</p>") + "\n"
137
+ end
138
+
139
+ def accept_verbatim(am, fragment)
140
+ @res << annotate("<pre>") + "\n"
141
+ @res << CGI.escapeHTML(fragment.txt)
142
+ @res << annotate("</pre>") << "\n"
143
+ end
144
+
145
+ def accept_rule(am, fragment)
146
+ size = fragment.param
147
+ size = 10 if size > 10
148
+ @res << "<hr size=\"#{size}\"></hr>"
149
+ end
150
+
151
+ def accept_list_start(am, fragment)
152
+ @res << html_list_name(fragment.type, true) << "\n"
153
+ @in_list_entry.push false
154
+ end
155
+
156
+ def accept_list_end(am, fragment)
157
+ if tag = @in_list_entry.pop
158
+ @res << annotate(tag) << "\n"
159
+ end
160
+ @res << html_list_name(fragment.type, false) << "\n"
161
+ end
162
+
163
+ def accept_list_item(am, fragment)
164
+ if tag = @in_list_entry.last
165
+ @res << annotate(tag) << "\n"
166
+ end
167
+
168
+ @res << list_item_start(am, fragment)
169
+
170
+ @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
171
+
172
+ @in_list_entry[-1] = list_end_for(fragment.type)
173
+ end
174
+
175
+ def accept_blank_line(am, fragment)
176
+ # @res << annotate("<p />") << "\n"
177
+ end
178
+
179
+ def accept_heading(am, fragment)
180
+ @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
181
+ end
182
+
183
+ ##
184
+ # This is a higher speed (if messier) version of wrap
185
+
186
+ def wrap(txt, line_len = 76)
187
+ res = ""
188
+ sp = 0
189
+ ep = txt.length
190
+ while sp < ep
191
+ # scan back for a space
192
+ p = sp + line_len - 1
193
+ if p >= ep
194
+ p = ep
195
+ else
196
+ while p > sp and txt[p] != ?\s
197
+ p -= 1
198
+ end
199
+ if p <= sp
200
+ p = sp + line_len
201
+ while p < ep and txt[p] != ?\s
202
+ p += 1
203
+ end
204
+ end
205
+ end
206
+ res << txt[sp...p] << "\n"
207
+ sp = p
208
+ sp += 1 while sp < ep and txt[sp] == ?\s
209
+ end
210
+ res
211
+ end
212
+
213
+ private
214
+
215
+ def on_tags(res, item)
216
+ attr_mask = item.turn_on
217
+ return if attr_mask.zero?
218
+
219
+ @attr_tags.each do |tag|
220
+ if attr_mask & tag.bit != 0
221
+ res << annotate(tag.on)
222
+ end
223
+ end
224
+ end
225
+
226
+ def off_tags(res, item)
227
+ attr_mask = item.turn_off
228
+ return if attr_mask.zero?
229
+
230
+ @attr_tags.reverse_each do |tag|
231
+ if attr_mask & tag.bit != 0
232
+ res << annotate(tag.off)
233
+ end
234
+ end
235
+ end
236
+
237
+ def convert_flow(flow)
238
+ res = ""
239
+
240
+ flow.each do |item|
241
+ case item
242
+ when String
243
+ res << convert_string(item)
244
+ when RDocF95::Markup::AttrChanger
245
+ off_tags(res, item)
246
+ on_tags(res, item)
247
+ when RDocF95::Markup::Special
248
+ res << convert_special(item)
249
+ else
250
+ raise "Unknown flow element: #{item.inspect}"
251
+ end
252
+ end
253
+
254
+ res
255
+ end
256
+
257
+ ##
258
+ # some of these patterns are taken from SmartyPants...
259
+
260
+ def convert_string(item)
261
+ CGI.escapeHTML(item).
262
+
263
+ # convert -- to em-dash, (-- to en-dash)
264
+ gsub(/---?/, '&#8212;'). #gsub(/--/, '&#8211;').
265
+
266
+ # convert ... to elipsis (and make sure .... becomes .<elipsis>)
267
+ gsub(/\.\.\.\./, '.&#8230;').gsub(/\.\.\./, '&#8230;').
268
+
269
+ # convert single closing quote
270
+ gsub(%r{([^ \t\r\n\[\{\(])\'}, '\1&#8217;').
271
+ gsub(%r{\'(?=\W|s\b)}, '&#8217;').
272
+
273
+ # convert single opening quote
274
+ gsub(/'/, '&#8216;').
275
+
276
+ # convert double closing quote
277
+ gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}, '\1&#8221;').
278
+
279
+ # convert double opening quote
280
+ gsub(/'/, '&#8220;').
281
+
282
+ # convert copyright
283
+ gsub(/\(c\)/, '&#169;').
284
+
285
+ # convert and registered trademark
286
+ gsub(/\(r\)/, '&#174;')
287
+
288
+ end
289
+
290
+ def convert_special(special)
291
+ handled = false
292
+ RDocF95::Markup::Attribute.each_name_of(special.type) do |name|
293
+ method_name = "handle_special_#{name}"
294
+ if self.respond_to? method_name
295
+ special.text = send(method_name, special)
296
+ handled = true
297
+ end
298
+ end
299
+ raise "Unhandled special: #{special}" unless handled
300
+ special.text
301
+ end
302
+
303
+ def convert_heading(level, flow)
304
+ res =
305
+ annotate("<h#{level}>") +
306
+ convert_flow(flow) +
307
+ annotate("</h#{level}>\n")
308
+ end
309
+
310
+ def html_list_name(list_type, is_open_tag)
311
+ tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}")
312
+ annotate(tags[ is_open_tag ? 0 : 1])
313
+ end
314
+
315
+ def list_item_start(am, fragment)
316
+ case fragment.type
317
+ when :BULLET, :NUMBER then
318
+ annotate("<li>")
319
+
320
+ when :UPPERALPHA then
321
+ annotate("<li type=\"A\">")
322
+
323
+ when :LOWERALPHA then
324
+ annotate("<li type=\"a\">")
325
+
326
+ when :LABELED then
327
+ annotate("<dt>") +
328
+ convert_flow(am.flow(fragment.param)) +
329
+ annotate("</dt>") +
330
+ annotate("<dd>")
331
+
332
+ when :NOTE then
333
+ annotate("<tr>") +
334
+ annotate("<td valign=\"top\">") +
335
+ convert_flow(am.flow(fragment.param)) +
336
+ annotate("</td>") +
337
+ annotate("<td>")
338
+ else
339
+ raise "Invalid list type"
340
+ end
341
+ end
342
+
343
+ def list_end_for(fragment_type)
344
+ case fragment_type
345
+ when :BULLET, :NUMBER, :UPPERALPHA, :LOWERALPHA then
346
+ "</li>"
347
+ when :LABELED then
348
+ "</dd>"
349
+ when :NOTE then
350
+ "</td></tr>"
351
+ else
352
+ raise "Invalid list type"
353
+ end
354
+ end
355
+
356
+ end
357
+
@@ -0,0 +1,123 @@
1
+ require 'rdoc-f95/markup/to_html'
2
+
3
+ ##
4
+ # Subclass of the RDocF95::Markup::ToHtml class that supports looking up words in
5
+ # the AllReferences list. Those that are found (like AllReferences in this
6
+ # comment) will be hyperlinked
7
+
8
+ class RDocF95::Markup::ToHtmlCrossref < RDocF95::Markup::ToHtml
9
+
10
+ attr_accessor :context
11
+
12
+ ##
13
+ # We need to record the html path of our caller so we can generate
14
+ # correct relative paths for any hyperlinks that we find
15
+
16
+ def initialize(from_path, context, show_hash)
17
+ super()
18
+
19
+ # class names, variable names, or instance variables
20
+ @markup.add_special(/(
21
+ # A::B.meth(**) (for operator and assignment in Fortran 90 or 95)
22
+ \b\w+(::\w+)*[\.\#]\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?
23
+ # meth(**) (for operator and assignment in Fortran 90 or 95)
24
+ | \#\w+(\([.\w\*\/\+\-\=\<\>]+\))?
25
+ | \b([A-Z]\w*(::\w+)*[.\#]\w+) # A::B.meth
26
+ | \b([A-Z]\w+(::\w+)*) # A::B
27
+ | \#\w+[!?=]? # #meth_name
28
+ | \\?\b\w+([_\/\.]+\w+)*[!?=]? # meth_name
29
+ )/x,
30
+ :CROSSREF)
31
+
32
+ # file names
33
+ @markup.add_special(/(
34
+ ((\/|\.\.\/|\.\/|\w)[\w\#\/\.\-\~\:]*[!?=]?) # file_name
35
+ | ((\/|\.\.\/|\.\/|\w)[\w\#\/\.\-\~\:]*(\([\.\w+\*\/\+\-\=\<\>]+\))?)
36
+ )/x,
37
+ :CROSSREFFILE)
38
+
39
+ @from_path = from_path
40
+ @context = context
41
+ @show_hash = show_hash
42
+
43
+ @seen = {}
44
+ @seen_file = {}
45
+ end
46
+
47
+ ##
48
+ # We're invoked when any text matches the CROSSREF pattern
49
+ # (defined in MarkUp). If we fine the corresponding reference,
50
+ # generate a hyperlink. If the name we're looking for contains
51
+ # no punctuation, we look for it up the module/class chain. For
52
+ # example, HyperlinkHtml is found, even without the Generator::
53
+ # prefix, because we look for it in module Generator first.
54
+
55
+ def handle_special_CROSSREF(special)
56
+ name = special.text
57
+
58
+ return @seen[name] if @seen.include? name
59
+
60
+ if name[0,1] == '#' then
61
+ lookup = name[1..-1]
62
+ name = lookup unless @show_hash
63
+ else
64
+ lookup = name
65
+ end
66
+
67
+ # Find class, module, or method in class or module.
68
+ if /([A-Z]\w*)[.\#](\w+[!?=]?)/ =~ lookup then
69
+ container = $1
70
+ method = $2
71
+ ref = @context.find_symbol container, method
72
+ elsif /([A-Za-z]\w*)[.\#](\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?)/ =~ lookup then
73
+ container = $1
74
+ method = $2
75
+ ref = @context.find_symbol container, method
76
+ else
77
+ ref = @context.find_symbol lookup
78
+ end
79
+
80
+ out = if lookup =~ /^\\/ then
81
+ $'
82
+ elsif ref and ref.document_self then
83
+ "<a href=\"#{ref.as_href(@from_path)}\">#{name}</a>"
84
+ else
85
+ name
86
+ end
87
+
88
+ @seen[name] = out
89
+
90
+ out
91
+ end
92
+
93
+ #
94
+ # CROSSREFFILE is similar to CROSSREF. But this pattern is
95
+ # hit to filenames or methods in files
96
+ #
97
+ def handle_special_CROSSREFFILE(special)
98
+ name = special.text
99
+
100
+ return @seen_file[name] if @seen_file.include? name
101
+
102
+ # Find file, or method in file
103
+ if /([\w\/\.].*\.\w+)[.\#](.*)/ =~ name
104
+ file_name = $1
105
+ method = $2
106
+ ref = @context.find_file file_name, method
107
+ else
108
+ ref = @context.find_file name
109
+ end
110
+
111
+ out = if ref and ref.document_self then
112
+ "<a href=\"#{ref.as_href(@from_path)}\">#{name}</a>"
113
+ else
114
+ name
115
+ end
116
+
117
+ @seen_file[name] = out
118
+
119
+ out
120
+
121
+ end
122
+
123
+ end