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,603 @@
1
+ require 'rdoc-f95/ri'
2
+ require 'rdoc-f95/markup'
3
+
4
+ class RDocF95::RI::Formatter
5
+
6
+ attr_reader :indent
7
+ attr_accessor :output
8
+
9
+ FORMATTERS = { }
10
+
11
+ def self.for(name)
12
+ FORMATTERS[name.downcase]
13
+ end
14
+
15
+ def self.list
16
+ FORMATTERS.keys.sort.join ", "
17
+ end
18
+
19
+ def initialize(output, width, indent)
20
+ @output = output
21
+ @width = width
22
+ @indent = indent
23
+ end
24
+
25
+ def draw_line(label=nil)
26
+ len = @width
27
+ len -= (label.size + 1) if label
28
+
29
+ if len > 0 then
30
+ @output.print '-' * len
31
+ if label
32
+ @output.print ' '
33
+ bold_print label
34
+ end
35
+
36
+ @output.puts
37
+ else
38
+ @output.print '-' * @width
39
+ @output.puts
40
+
41
+ @output.puts label
42
+ end
43
+ end
44
+
45
+ def wrap(txt, prefix=@indent, linelen=@width)
46
+ return unless txt && !txt.empty?
47
+
48
+ work = conv_markup(txt)
49
+ textLen = linelen - prefix.length
50
+ patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
51
+ next_prefix = prefix.tr("^ ", " ")
52
+
53
+ res = []
54
+
55
+ while work.length > textLen
56
+ if work =~ patt
57
+ res << $1
58
+ work.slice!(0, $&.length)
59
+ else
60
+ res << work.slice!(0, textLen)
61
+ end
62
+ end
63
+ res << work if work.length.nonzero?
64
+ @output.puts(prefix + res.join("\n" + next_prefix))
65
+ end
66
+
67
+ def blankline
68
+ @output.puts
69
+ end
70
+
71
+ ##
72
+ # Called when we want to ensure a new 'wrap' starts on a newline. Only
73
+ # needed for HtmlFormatter, because the rest do their own line breaking.
74
+
75
+ def break_to_newline
76
+ end
77
+
78
+ def bold_print(txt)
79
+ @output.print txt
80
+ end
81
+
82
+ def raw_print_line(txt)
83
+ @output.puts txt
84
+ end
85
+
86
+ ##
87
+ # Convert HTML entities back to ASCII
88
+
89
+ def conv_html(txt)
90
+ txt = txt.gsub(/&gt;/, '>')
91
+ txt.gsub!(/&lt;/, '<')
92
+ txt.gsub!(/&quot;/, '"')
93
+ txt.gsub!(/&amp;/, '&')
94
+ txt
95
+ end
96
+
97
+ ##
98
+ # Convert markup into display form
99
+
100
+ def conv_markup(txt)
101
+ txt = txt.gsub(%r{<tt>(.*?)</tt>}, '+\1+')
102
+ txt.gsub!(%r{<code>(.*?)</code>}, '+\1+')
103
+ txt.gsub!(%r{<b>(.*?)</b>}, '*\1*')
104
+ txt.gsub!(%r{<em>(.*?)</em>}, '_\1_')
105
+ txt
106
+ end
107
+
108
+ def display_list(list)
109
+ case list.type
110
+ when :BULLET
111
+ prefixer = proc { |ignored| @indent + "* " }
112
+
113
+ when :NUMBER, :UPPERALPHA, :LOWERALPHA then
114
+ start = case list.type
115
+ when :NUMBER then 1
116
+ when :UPPERALPHA then 'A'
117
+ when :LOWERALPHA then 'a'
118
+ end
119
+
120
+ prefixer = proc do |ignored|
121
+ res = @indent + "#{start}.".ljust(4)
122
+ start = start.succ
123
+ res
124
+ end
125
+
126
+ when :LABELED, :NOTE then
127
+ longest = 0
128
+
129
+ list.contents.each do |item|
130
+ if RDocF95::Markup::Flow::LI === item and item.label.length > longest then
131
+ longest = item.label.length
132
+ end
133
+ end
134
+
135
+ longest += 1
136
+
137
+ prefixer = proc { |li| @indent + li.label.ljust(longest) }
138
+
139
+ else
140
+ raise ArgumentError, "unknown list type #{list.type}"
141
+ end
142
+
143
+ list.contents.each do |item|
144
+ if RDocF95::Markup::Flow::LI === item then
145
+ prefix = prefixer.call item
146
+ display_flow_item item, prefix
147
+ else
148
+ display_flow_item item
149
+ end
150
+ end
151
+ end
152
+
153
+ def display_flow_item(item, prefix = @indent)
154
+ case item
155
+ when RDocF95::Markup::Flow::P, RDocF95::Markup::Flow::LI
156
+ wrap(conv_html(item.body), prefix)
157
+ blankline
158
+
159
+ when RDocF95::Markup::Flow::LIST
160
+ display_list(item)
161
+
162
+ when RDocF95::Markup::Flow::VERB
163
+ display_verbatim_flow_item(item, @indent)
164
+
165
+ when RDocF95::Markup::Flow::H
166
+ display_heading(conv_html(item.text), item.level, @indent)
167
+
168
+ when RDocF95::Markup::Flow::RULE
169
+ draw_line
170
+
171
+ else
172
+ raise RDocF95::Error, "Unknown flow element: #{item.class}"
173
+ end
174
+ end
175
+
176
+ def display_verbatim_flow_item(item, prefix=@indent)
177
+ item.body.split(/\n/).each do |line|
178
+ @output.print @indent, conv_html(line), "\n"
179
+ end
180
+ blankline
181
+ end
182
+
183
+ def display_heading(text, level, indent)
184
+ text = strip_attributes text
185
+
186
+ case level
187
+ when 1 then
188
+ ul = "=" * text.length
189
+ @output.puts
190
+ @output.puts text.upcase
191
+ @output.puts ul
192
+
193
+ when 2 then
194
+ ul = "-" * text.length
195
+ @output.puts
196
+ @output.puts text
197
+ @output.puts ul
198
+ else
199
+ @output.print indent, text, "\n"
200
+ end
201
+
202
+ @output.puts
203
+ end
204
+
205
+ def display_flow(flow)
206
+ flow.each do |f|
207
+ display_flow_item(f)
208
+ end
209
+ end
210
+
211
+ def strip_attributes(text)
212
+ text.gsub(/(<\/?(?:b|code|em|i|tt)>)/, '')
213
+ end
214
+
215
+ end
216
+
217
+ ##
218
+ # Handle text with attributes. We're a base class: there are different
219
+ # presentation classes (one, for example, uses overstrikes to handle bold and
220
+ # underlining, while another using ANSI escape sequences.
221
+
222
+ class RDocF95::RI::AttributeFormatter < RDocF95::RI::Formatter
223
+
224
+ BOLD = 1
225
+ ITALIC = 2
226
+ CODE = 4
227
+
228
+ ATTR_MAP = {
229
+ "b" => BOLD,
230
+ "code" => CODE,
231
+ "em" => ITALIC,
232
+ "i" => ITALIC,
233
+ "tt" => CODE
234
+ }
235
+
236
+ AttrChar = Struct.new :char, :attr
237
+
238
+ class AttributeString
239
+ attr_reader :txt
240
+
241
+ def initialize
242
+ @txt = []
243
+ @optr = 0
244
+ end
245
+
246
+ def <<(char)
247
+ @txt << char
248
+ end
249
+
250
+ def empty?
251
+ @optr >= @txt.length
252
+ end
253
+
254
+ # accept non space, then all following spaces
255
+ def next_word
256
+ start = @optr
257
+ len = @txt.length
258
+
259
+ while @optr < len && @txt[@optr].char != " "
260
+ @optr += 1
261
+ end
262
+
263
+ while @optr < len && @txt[@optr].char == " "
264
+ @optr += 1
265
+ end
266
+
267
+ @txt[start...@optr]
268
+ end
269
+ end
270
+
271
+ ##
272
+ # Overrides base class. Looks for <tt>...</tt> etc sequences and generates
273
+ # an array of AttrChars. This array is then used as the basis for the
274
+ # split.
275
+
276
+ def wrap(txt, prefix=@indent, linelen=@width)
277
+ return unless txt && !txt.empty?
278
+
279
+ txt = add_attributes_to(txt)
280
+ next_prefix = prefix.tr("^ ", " ")
281
+ linelen -= prefix.size
282
+
283
+ line = []
284
+
285
+ until txt.empty?
286
+ word = txt.next_word
287
+ if word.size + line.size > linelen
288
+ write_attribute_text(prefix, line)
289
+ prefix = next_prefix
290
+ line = []
291
+ end
292
+ line.concat(word)
293
+ end
294
+
295
+ write_attribute_text(prefix, line) if line.length > 0
296
+ end
297
+
298
+ protected
299
+
300
+ def write_attribute_text(prefix, line)
301
+ @output.print prefix
302
+ line.each do |achar|
303
+ @output.print achar.char
304
+ end
305
+ @output.puts
306
+ end
307
+
308
+ def bold_print(txt)
309
+ @output.print txt
310
+ end
311
+
312
+ private
313
+
314
+ def add_attributes_to(txt)
315
+ tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})
316
+ text = AttributeString.new
317
+ attributes = 0
318
+ tokens.each do |tok|
319
+ case tok
320
+ when %r{^</(\w+)>$} then attributes &= ~(ATTR_MAP[$1]||0)
321
+ when %r{^<(\w+)>$} then attributes |= (ATTR_MAP[$1]||0)
322
+ else
323
+ tok.split(//).each {|ch| text << AttrChar.new(ch, attributes)}
324
+ end
325
+ end
326
+ text
327
+ end
328
+
329
+ end
330
+
331
+ ##
332
+ # This formatter generates overstrike-style formatting, which works with
333
+ # pagers such as man and less.
334
+
335
+ class RDocF95::RI::OverstrikeFormatter < RDocF95::RI::AttributeFormatter
336
+
337
+ BS = "\C-h"
338
+
339
+ def write_attribute_text(prefix, line)
340
+ @output.print prefix
341
+
342
+ line.each do |achar|
343
+ attr = achar.attr
344
+ @output.print "_", BS if (attr & (ITALIC + CODE)) != 0
345
+ @output.print achar.char, BS if (attr & BOLD) != 0
346
+ @output.print achar.char
347
+ end
348
+
349
+ @output.puts
350
+ end
351
+
352
+ ##
353
+ # Draw a string in bold
354
+
355
+ def bold_print(text)
356
+ text.split(//).each do |ch|
357
+ @output.print ch, BS, ch
358
+ end
359
+ end
360
+
361
+ end
362
+
363
+ ##
364
+ # This formatter uses ANSI escape sequences to colorize stuff works with
365
+ # pagers such as man and less.
366
+
367
+ class RDocF95::RI::AnsiFormatter < RDocF95::RI::AttributeFormatter
368
+
369
+ def initialize(*args)
370
+ super
371
+ @output.print "\033[0m"
372
+ end
373
+
374
+ def write_attribute_text(prefix, line)
375
+ @output.print prefix
376
+ curr_attr = 0
377
+ line.each do |achar|
378
+ attr = achar.attr
379
+ if achar.attr != curr_attr
380
+ update_attributes(achar.attr)
381
+ curr_attr = achar.attr
382
+ end
383
+ @output.print achar.char
384
+ end
385
+ update_attributes(0) unless curr_attr.zero?
386
+ @output.puts
387
+ end
388
+
389
+ def bold_print(txt)
390
+ @output.print "\033[1m#{txt}\033[m"
391
+ end
392
+
393
+ HEADINGS = {
394
+ 1 => ["\033[1;32m", "\033[m"],
395
+ 2 => ["\033[4;32m", "\033[m"],
396
+ 3 => ["\033[32m", "\033[m"],
397
+ }
398
+
399
+ def display_heading(text, level, indent)
400
+ level = 3 if level > 3
401
+ heading = HEADINGS[level]
402
+ @output.print indent
403
+ @output.print heading[0]
404
+ @output.print strip_attributes(text)
405
+ @output.puts heading[1]
406
+ end
407
+
408
+ private
409
+
410
+ ATTR_MAP = {
411
+ BOLD => "1",
412
+ ITALIC => "33",
413
+ CODE => "36"
414
+ }
415
+
416
+ def update_attributes(attr)
417
+ str = "\033["
418
+ for quality in [ BOLD, ITALIC, CODE]
419
+ unless (attr & quality).zero?
420
+ str << ATTR_MAP[quality]
421
+ end
422
+ end
423
+ @output.print str, "m"
424
+ end
425
+
426
+ end
427
+
428
+ ##
429
+ # This formatter uses HTML.
430
+
431
+ class RDocF95::RI::HtmlFormatter < RDocF95::RI::AttributeFormatter
432
+
433
+ def write_attribute_text(prefix, line)
434
+ curr_attr = 0
435
+ line.each do |achar|
436
+ attr = achar.attr
437
+ if achar.attr != curr_attr
438
+ update_attributes(curr_attr, achar.attr)
439
+ curr_attr = achar.attr
440
+ end
441
+ @output.print(escape(achar.char))
442
+ end
443
+ update_attributes(curr_attr, 0) unless curr_attr.zero?
444
+ end
445
+
446
+ def draw_line(label=nil)
447
+ if label != nil
448
+ bold_print(label)
449
+ end
450
+ @output.puts("<hr>")
451
+ end
452
+
453
+ def bold_print(txt)
454
+ tag("b") { txt }
455
+ end
456
+
457
+ def blankline()
458
+ @output.puts("<p>")
459
+ end
460
+
461
+ def break_to_newline
462
+ @output.puts("<br>")
463
+ end
464
+
465
+ def display_heading(text, level, indent)
466
+ level = 4 if level > 4
467
+ tag("h#{level}") { text }
468
+ @output.puts
469
+ end
470
+
471
+ def display_list(list)
472
+ case list.type
473
+ when :BULLET then
474
+ list_type = "ul"
475
+ prefixer = proc { |ignored| "<li>" }
476
+
477
+ when :NUMBER, :UPPERALPHA, :LOWERALPHA then
478
+ list_type = "ol"
479
+ prefixer = proc { |ignored| "<li>" }
480
+
481
+ when :LABELED then
482
+ list_type = "dl"
483
+ prefixer = proc do |li|
484
+ "<dt><b>" + escape(li.label) + "</b><dd>"
485
+ end
486
+
487
+ when :NOTE then
488
+ list_type = "table"
489
+ prefixer = proc do |li|
490
+ %{<tr valign="top"><td>#{li.label.gsub(/ /, '&nbsp;')}</td><td>}
491
+ end
492
+ else
493
+ fail "unknown list type"
494
+ end
495
+
496
+ @output.print "<#{list_type}>"
497
+ list.contents.each do |item|
498
+ if item.kind_of? RDocF95::Markup::Flow::LI
499
+ prefix = prefixer.call(item)
500
+ @output.print prefix
501
+ display_flow_item(item, prefix)
502
+ else
503
+ display_flow_item(item)
504
+ end
505
+ end
506
+ @output.print "</#{list_type}>"
507
+ end
508
+
509
+ def display_verbatim_flow_item(item, prefix=@indent)
510
+ @output.print("<pre>")
511
+ item.body.split(/\n/).each do |line|
512
+ @output.puts conv_html(line)
513
+ end
514
+ @output.puts("</pre>")
515
+ end
516
+
517
+ private
518
+
519
+ ATTR_MAP = {
520
+ BOLD => "b>",
521
+ ITALIC => "i>",
522
+ CODE => "tt>"
523
+ }
524
+
525
+ def update_attributes(current, wanted)
526
+ str = ""
527
+ # first turn off unwanted ones
528
+ off = current & ~wanted
529
+ for quality in [ BOLD, ITALIC, CODE]
530
+ if (off & quality) > 0
531
+ str << "</" + ATTR_MAP[quality]
532
+ end
533
+ end
534
+
535
+ # now turn on wanted
536
+ for quality in [ BOLD, ITALIC, CODE]
537
+ unless (wanted & quality).zero?
538
+ str << "<" << ATTR_MAP[quality]
539
+ end
540
+ end
541
+ @output.print str
542
+ end
543
+
544
+ def tag(code)
545
+ @output.print("<#{code}>")
546
+ @output.print(yield)
547
+ @output.print("</#{code}>")
548
+ end
549
+
550
+ def escape(str)
551
+ str = str.gsub(/&/n, '&amp;')
552
+ str.gsub!(/\"/n, '&quot;')
553
+ str.gsub!(/>/n, '&gt;')
554
+ str.gsub!(/</n, '&lt;')
555
+ str
556
+ end
557
+
558
+ end
559
+
560
+ ##
561
+ # This formatter reduces extra lines for a simpler output. It improves way
562
+ # output looks for tools like IRC bots.
563
+
564
+ class RDocF95::RI::SimpleFormatter < RDocF95::RI::Formatter
565
+
566
+ ##
567
+ # No extra blank lines
568
+
569
+ def blankline
570
+ end
571
+
572
+ ##
573
+ # Display labels only, no lines
574
+
575
+ def draw_line(label=nil)
576
+ unless label.nil? then
577
+ bold_print(label)
578
+ @output.puts
579
+ end
580
+ end
581
+
582
+ ##
583
+ # Place heading level indicators inline with heading.
584
+
585
+ def display_heading(text, level, indent)
586
+ text = strip_attributes(text)
587
+ case level
588
+ when 1
589
+ @output.puts "= " + text.upcase
590
+ when 2
591
+ @output.puts "-- " + text
592
+ else
593
+ @output.print indent, text, "\n"
594
+ end
595
+ end
596
+
597
+ end
598
+
599
+ RDocF95::RI::Formatter::FORMATTERS['plain'] = RDocF95::RI::Formatter
600
+ RDocF95::RI::Formatter::FORMATTERS['simple'] = RDocF95::RI::SimpleFormatter
601
+ RDocF95::RI::Formatter::FORMATTERS['bs'] = RDocF95::RI::OverstrikeFormatter
602
+ RDocF95::RI::Formatter::FORMATTERS['ansi'] = RDocF95::RI::AnsiFormatter
603
+ RDocF95::RI::Formatter::FORMATTERS['html'] = RDocF95::RI::HtmlFormatter