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.
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,506 @@
1
+ ##
2
+ # RDocF95::Markup parses plain text documents and attempts to decompose them into
3
+ # their constituent parts. Some of these parts are high-level: paragraphs,
4
+ # chunks of verbatim text, list entries and the like. Other parts happen at
5
+ # the character level: a piece of bold text, a word in code font. This markup
6
+ # is similar in spirit to that used on WikiWiki webs, where folks create web
7
+ # pages using a simple set of formatting rules.
8
+ #
9
+ # RDocF95::Markup itself does no output formatting: this is left to a different
10
+ # set of classes.
11
+ #
12
+ # RDocF95::Markup is extendable at runtime: you can add new markup elements to be
13
+ # recognised in the documents that RDocF95::Markup parses.
14
+ #
15
+ # RDocF95::Markup is intended to be the basis for a family of tools which share
16
+ # the common requirement that simple, plain-text should be rendered in a
17
+ # variety of different output formats and media. It is envisaged that
18
+ # RDocF95::Markup could be the basis for formating RDoc style comment blocks,
19
+ # Wiki entries, and online FAQs.
20
+ #
21
+ # = Basic Formatting
22
+ #
23
+ # * RDocF95::Markup looks for a document's natural left margin. This is
24
+ # used as the initial margin for the document.
25
+ #
26
+ # * Consecutive lines starting at this margin are considered to be a
27
+ # paragraph.
28
+ #
29
+ # * If a paragraph starts with a "*", "-", or with "<digit>.", then it is
30
+ # taken to be the start of a list. The margin in increased to be the
31
+ # first non-space following the list start flag. Subsequent lines
32
+ # should be indented to this new margin until the list ends. For
33
+ # example:
34
+ #
35
+ # * this is a list with three paragraphs in
36
+ # the first item. This is the first paragraph.
37
+ #
38
+ # And this is the second paragraph.
39
+ #
40
+ # 1. This is an indented, numbered list.
41
+ # 2. This is the second item in that list
42
+ #
43
+ # This is the third conventional paragraph in the
44
+ # first list item.
45
+ #
46
+ # * This is the second item in the original list
47
+ #
48
+ # * You can also construct labeled lists, sometimes called description
49
+ # or definition lists. Do this by putting the label in square brackets
50
+ # and indenting the list body:
51
+ #
52
+ # [cat] a small furry mammal
53
+ # that seems to sleep a lot
54
+ #
55
+ # [ant] a little insect that is known
56
+ # to enjoy picnics
57
+ #
58
+ # A minor variation on labeled lists uses two colons to separate the
59
+ # label from the list body:
60
+ #
61
+ # cat:: a small furry mammal
62
+ # that seems to sleep a lot
63
+ #
64
+ # ant:: a little insect that is known
65
+ # to enjoy picnics
66
+ #
67
+ # This latter style guarantees that the list bodies' left margins are
68
+ # aligned: think of them as a two column table.
69
+ #
70
+ # * Any line that starts to the right of the current margin is treated
71
+ # as verbatim text. This is useful for code listings. The example of a
72
+ # list above is also verbatim text.
73
+ #
74
+ # * A line starting with an equals sign (=) is treated as a
75
+ # heading. Level one headings have one equals sign, level two headings
76
+ # have two,and so on.
77
+ #
78
+ # * A line starting with three or more hyphens (at the current indent)
79
+ # generates a horizontal rule. The more hyphens, the thicker the rule
80
+ # (within reason, and if supported by the output device)
81
+ #
82
+ # * You can use markup within text (except verbatim) to change the
83
+ # appearance of parts of that text. Out of the box, RDocF95::Markup
84
+ # supports word-based and general markup.
85
+ #
86
+ # Word-based markup uses flag characters around individual words:
87
+ #
88
+ # [\*word*] displays word in a *bold* font
89
+ # [\_word_] displays word in an _emphasized_ font
90
+ # [\+word+] displays word in a +code+ font
91
+ #
92
+ # General markup affects text between a start delimiter and and end
93
+ # delimiter. Not surprisingly, these delimiters look like HTML markup.
94
+ #
95
+ # [\<b>text...</b>] displays word in a *bold* font
96
+ # [\<em>text...</em>] displays word in an _emphasized_ font
97
+ # [\<i>text...</i>] displays word in an _emphasized_ font
98
+ # [\<tt>text...</tt>] displays word in a +code+ font
99
+ #
100
+ # Unlike conventional Wiki markup, general markup can cross line
101
+ # boundaries. You can turn off the interpretation of markup by
102
+ # preceding the first character with a backslash, so \\\<b>bold
103
+ # text</b> and \\\*bold* produce \<b>bold text</b> and \*bold
104
+ # respectively.
105
+ #
106
+ # * Hyperlinks to the web starting http:, mailto:, ftp:, or www. are
107
+ # recognized. An HTTP url that references an external image file is
108
+ # converted into an inline <IMG..>. Hyperlinks starting 'link:' are
109
+ # assumed to refer to local files whose path is relative to the --op
110
+ # directory.
111
+ #
112
+ # Hyperlinks can also be of the form <tt>label</tt>[url], in which
113
+ # case the label is used in the displayed text, and <tt>url</tt> is
114
+ # used as the target. If <tt>label</tt> contains multiple words,
115
+ # put it in braces: <em>{multi word label}[</em>url<em>]</em>.
116
+ #
117
+ # == Synopsis
118
+ #
119
+ # This code converts <tt>input_string</tt> to HTML. The conversion
120
+ # takes place in the +convert+ method, so you can use the same
121
+ # RDocF95::Markup object to convert multiple input strings.
122
+ #
123
+ # require 'rdoc-f95/markup'
124
+ # require 'rdoc-f95/markup/to_html'
125
+ #
126
+ # p = RDocF95::Markup.new
127
+ # h = RDocF95::Markup::ToHtml.new
128
+ #
129
+ # puts p.convert(input_string, h)
130
+ #
131
+ # You can extend the RDocF95::Markup parser to recognise new markup
132
+ # sequences, and to add special processing for text that matches a
133
+ # regular epxression. Here we make WikiWords significant to the parser,
134
+ # and also make the sequences {word} and \<no>text...</no> signify
135
+ # strike-through text. When then subclass the HTML output class to deal
136
+ # with these:
137
+ #
138
+ # require 'rdoc-f95/markup'
139
+ # require 'rdoc-f95/markup/to_html'
140
+ #
141
+ # class WikiHtml < RDocF95::Markup::ToHtml
142
+ # def handle_special_WIKIWORD(special)
143
+ # "<font color=red>" + special.text + "</font>"
144
+ # end
145
+ # end
146
+ #
147
+ # m = RDocF95::Markup.new
148
+ # m.add_word_pair("{", "}", :STRIKE)
149
+ # m.add_html("no", :STRIKE)
150
+ #
151
+ # m.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
152
+ #
153
+ # h = WikiHtml.new
154
+ # h.add_tag(:STRIKE, "<strike>", "</strike>")
155
+ #
156
+ # puts "<body>" + m.convert(ARGF.read, h) + "</body>"
157
+ #
158
+ #--
159
+ # Author:: Dave Thomas, dave@pragmaticprogrammer.com
160
+ # License:: Ruby license
161
+
162
+ class RDocF95::Markup
163
+
164
+ SPACE = ?\s
165
+
166
+ # List entries look like:
167
+ # * text
168
+ # 1. text
169
+ # [label] text
170
+ # label:: text
171
+ #
172
+ # Flag it as a list entry, and work out the indent for subsequent lines
173
+
174
+ SIMPLE_LIST_RE = /^(
175
+ ( \* (?# bullet)
176
+ |- (?# bullet)
177
+ |\d+\. (?# numbered )
178
+ |[A-Za-z]\. (?# alphabetically numbered )
179
+ )
180
+ \s+
181
+ )\S/x
182
+
183
+ LABEL_LIST_RE = /^(
184
+ ( \[.*?\] (?# labeled )
185
+ |\S.*:: (?# note )
186
+ )(?:\s+|$)
187
+ )/x
188
+
189
+ ##
190
+ # Take a block of text and use various heuristics to determine it's
191
+ # structure (paragraphs, lists, and so on). Invoke an event handler as we
192
+ # identify significant chunks.
193
+
194
+ def initialize
195
+ @am = RDocF95::Markup::AttributeManager.new
196
+ @output = nil
197
+ end
198
+
199
+ ##
200
+ # Add to the sequences used to add formatting to an individual word (such
201
+ # as *bold*). Matching entries will generate attibutes that the output
202
+ # formatters can recognize by their +name+.
203
+
204
+ def add_word_pair(start, stop, name)
205
+ @am.add_word_pair(start, stop, name)
206
+ end
207
+
208
+ ##
209
+ # Add to the sequences recognized as general markup.
210
+
211
+ def add_html(tag, name)
212
+ @am.add_html(tag, name)
213
+ end
214
+
215
+ ##
216
+ # Add to other inline sequences. For example, we could add WikiWords using
217
+ # something like:
218
+ #
219
+ # parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
220
+ #
221
+ # Each wiki word will be presented to the output formatter via the
222
+ # accept_special method.
223
+
224
+ def add_special(pattern, name)
225
+ @am.add_special(pattern, name)
226
+ end
227
+
228
+ ##
229
+ # We take a string, split it into lines, work out the type of each line,
230
+ # and from there deduce groups of lines (for example all lines in a
231
+ # paragraph). We then invoke the output formatter using a Visitor to
232
+ # display the result.
233
+
234
+ def convert(str, op, block_exceptions=nil)
235
+ lines = str.split(/\r?\n/).map { |line| Line.new line }
236
+ @lines = Lines.new lines
237
+ @block_exceptions = block_exceptions
238
+
239
+ return "" if @lines.empty?
240
+ @lines.normalize
241
+ assign_types_to_lines
242
+ group = group_lines
243
+ # call the output formatter to handle the result
244
+ #group.each { |line| p line }
245
+ group.accept @am, op
246
+ end
247
+
248
+ private
249
+
250
+ ##
251
+ # Look through the text at line indentation. We flag each line as being
252
+ # Blank, a paragraph, a list element, or verbatim text.
253
+
254
+ def assign_types_to_lines(margin = 0, level = 0)
255
+ now_blocking = false
256
+ while line = @lines.next
257
+ if line.blank? then
258
+ line.stamp :BLANK, level
259
+ next
260
+ end
261
+
262
+ # if a line contains non-blanks before the margin, then it must belong
263
+ # to an outer level
264
+
265
+ text = line.text
266
+
267
+ for i in 0...margin
268
+ if text[i] != SPACE
269
+ @lines.unget
270
+ return
271
+ end
272
+ end
273
+
274
+ active_line = text[margin..-1]
275
+
276
+ #
277
+ # block_exceptions checking
278
+ #
279
+ if @block_exceptions
280
+ if now_blocking
281
+ line.stamp(:PARAGRAPH, level)
282
+ @block_exceptions.each{ |be|
283
+ if now_blocking == be['name']
284
+ be['replaces'].each{ |rep|
285
+ line.text.gsub!(rep['from'], rep['to'])
286
+ }
287
+ end
288
+ if now_blocking == be['name'] && line.text =~ be['end']
289
+ now_blocking = false
290
+ break
291
+ end
292
+ }
293
+ next
294
+ else
295
+ @block_exceptions.each{ |be|
296
+ if line.text =~ be['start']
297
+ now_blocking = be['name']
298
+ line.stamp(:PARAGRAPH, level)
299
+ break
300
+ end
301
+ }
302
+ next if now_blocking
303
+ end
304
+ end
305
+
306
+ # Rules (horizontal lines) look like
307
+ #
308
+ # --- (three or more hyphens)
309
+ #
310
+ # The more hyphens, the thicker the rule
311
+ #
312
+
313
+ if /^(---+)\s*$/ =~ active_line
314
+ line.stamp :RULE, level, $1.length-2
315
+ next
316
+ end
317
+
318
+ # Then look for list entries. First the ones that have to have
319
+ # text following them (* xxx, - xxx, and dd. xxx)
320
+
321
+ if SIMPLE_LIST_RE =~ active_line
322
+ offset = margin + $1.length
323
+ prefix = $2
324
+ prefix_length = prefix.length
325
+
326
+ flag = case prefix
327
+ when "*","-" then :BULLET
328
+ when /^\d/ then :NUMBER
329
+ when /^[A-Z]/ then :UPPERALPHA
330
+ when /^[a-z]/ then :LOWERALPHA
331
+ else raise "Invalid List Type: #{self.inspect}"
332
+ end
333
+
334
+ line.stamp :LIST, level+1, prefix, flag
335
+ text[margin, prefix_length] = " " * prefix_length
336
+ assign_types_to_lines(offset, level + 1)
337
+ next
338
+ end
339
+
340
+ if LABEL_LIST_RE =~ active_line
341
+ offset = margin + $1.length
342
+ prefix = $2
343
+ prefix_length = prefix.length
344
+
345
+ next if handled_labeled_list(line, level, margin, offset, prefix)
346
+ end
347
+
348
+ # Headings look like
349
+ # = Main heading
350
+ # == Second level
351
+ # === Third
352
+ #
353
+ # Headings reset the level to 0
354
+
355
+ if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/
356
+ prefix_length = $1.length
357
+ prefix_length = 6 if prefix_length > 6
358
+ line.stamp :HEADING, 0, prefix_length
359
+ line.strip_leading(margin + prefix_length)
360
+ next
361
+ end
362
+
363
+ # If the character's a space, then we have verbatim text,
364
+ # otherwise
365
+
366
+ if active_line[0] == SPACE
367
+ line.strip_leading(margin) if margin > 0
368
+ line.stamp :VERBATIM, level
369
+ else
370
+ line.stamp :PARAGRAPH, level
371
+ end
372
+ end
373
+ end
374
+
375
+ ##
376
+ # Handle labeled list entries, We have a special case to deal with.
377
+ # Because the labels can be long, they force the remaining block of text
378
+ # over the to right:
379
+ #
380
+ # this is a long label that I wrote:: and here is the
381
+ # block of text with
382
+ # a silly margin
383
+ #
384
+ # So we allow the special case. If the label is followed by nothing, and
385
+ # if the following line is indented, then we take the indent of that line
386
+ # as the new margin.
387
+ #
388
+ # this is a long label that I wrote::
389
+ # here is a more reasonably indented block which
390
+ # will be attached to the label.
391
+ #
392
+
393
+ def handled_labeled_list(line, level, margin, offset, prefix)
394
+ prefix_length = prefix.length
395
+ text = line.text
396
+ flag = nil
397
+
398
+ case prefix
399
+ when /^\[/ then
400
+ flag = :LABELED
401
+ prefix = prefix[1, prefix.length-2]
402
+ when /:$/ then
403
+ flag = :NOTE
404
+ prefix.chop!
405
+ else
406
+ raise "Invalid List Type: #{self.inspect}"
407
+ end
408
+
409
+ # body is on the next line
410
+ if text.length <= offset then
411
+ original_line = line
412
+ line = @lines.next
413
+ return false unless line
414
+ text = line.text
415
+
416
+ for i in 0..margin
417
+ if text[i] != SPACE
418
+ @lines.unget
419
+ return false
420
+ end
421
+ end
422
+
423
+ i = margin
424
+ i += 1 while text[i] == SPACE
425
+
426
+ if i >= text.length then
427
+ @lines.unget
428
+ return false
429
+ else
430
+ offset = i
431
+ prefix_length = 0
432
+
433
+ if text[offset..-1] =~ SIMPLE_LIST_RE then
434
+ @lines.unget
435
+ line = original_line
436
+ line.text = ''
437
+ else
438
+ @lines.delete original_line
439
+ end
440
+ end
441
+ end
442
+
443
+ line.stamp :LIST, level+1, prefix, flag
444
+ text[margin, prefix_length] = " " * prefix_length
445
+ assign_types_to_lines(offset, level + 1)
446
+ return true
447
+ end
448
+
449
+ ##
450
+ # Return a block consisting of fragments which are paragraphs, list
451
+ # entries or verbatim text. We merge consecutive lines of the same type
452
+ # and level together. We are also slightly tricky with lists: the lines
453
+ # following a list introduction look like paragraph lines at the next
454
+ # level, and we remap them into list entries instead.
455
+
456
+ def group_lines
457
+ @lines.rewind
458
+
459
+ in_list = false
460
+ wanted_type = wanted_level = nil
461
+
462
+ block = LineCollection.new
463
+ group = nil
464
+
465
+ while line = @lines.next
466
+ if line.level == wanted_level and line.type == wanted_type
467
+ group.add_text(line.text)
468
+ else
469
+ group = block.fragment_for(line)
470
+ block.add(group)
471
+
472
+ if line.type == :LIST
473
+ wanted_type = :PARAGRAPH
474
+ else
475
+ wanted_type = line.type
476
+ end
477
+
478
+ wanted_level = line.type == :HEADING ? line.param : line.level
479
+ end
480
+ end
481
+
482
+ block.normalize
483
+ block
484
+ end
485
+
486
+ ##
487
+ # For debugging, we allow access to our line contents as text.
488
+
489
+ def content
490
+ @lines.as_text
491
+ end
492
+ public :content
493
+
494
+ ##
495
+ # For debugging, return the list of line types.
496
+
497
+ def get_line_types
498
+ @lines.line_types
499
+ end
500
+ public :get_line_types
501
+
502
+ end
503
+
504
+ require 'rdoc-f95/markup/fragments'
505
+ require 'rdoc-f95/markup/inline'
506
+ require 'rdoc-f95/markup/lines'