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,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'