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,57 @@
1
+ require 'rbconfig'
2
+ require 'find'
3
+ require 'fileutils'
4
+ require 'optparse'
5
+
6
+ include Config
7
+
8
+ opt = OptionParser.new
9
+ libdir = nil
10
+ opt.on('--libdir=VAL') {|v| libdir = v}
11
+ opt.parse!(ARGV)
12
+
13
+ libdir = File.expand_path(libdir) if libdir
14
+
15
+ if libdir
16
+ sitedir = libdir
17
+ else
18
+ sitedir = CONFIG["sitelibdir"]
19
+ unless sitedir
20
+ version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
21
+ libdir = File.join(CONFIG["libdir"], "ruby", version)
22
+ sitedir = $:.find {|x| x =~ /site_ruby/}
23
+ if !sitedir
24
+ sitedir = File.join(libdir, "site_ruby")
25
+ elsif sitedir !~ Regexp.quote(version)
26
+ sitedir = File.join(sitedir, version)
27
+ end
28
+ end
29
+ end
30
+
31
+ unless /^\// =~ sitedir.strip
32
+ sitedir = File.join("..", sitedir)
33
+ end
34
+
35
+ if !File.directory?(sitedir)
36
+ $stderr.puts "Cannot find sitedir #{sitedir}"
37
+ exit 1
38
+ end
39
+
40
+ rdoc_dest = File.join(sitedir, "rdoc")
41
+
42
+ dest = File.join(rdoc_dest, "markup")
43
+
44
+ FileUtils::makedirs(dest, {:verbose => true})
45
+
46
+ Find.find("./",
47
+ "sample") do |fname|
48
+ if File.directory?(fname)
49
+ next if fname =~ /CVS/
50
+ FileUtils::makedirs(File.join(dest, fname), {:verbose => true})
51
+ else
52
+ next unless fname =~ /\.rb$/
53
+ next if fname =~ /install.rb$/
54
+ FileUtils::install(fname, File.join(dest, fname),
55
+ {:mode => 0444, :verbose => true})
56
+ end
57
+ end
@@ -0,0 +1,152 @@
1
+ class RDocF95::Markup
2
+
3
+ ##
4
+ # We store the lines we're working on as objects of class Line. These
5
+ # contain the text of the line, along with a flag indicating the line type,
6
+ # and an indentation level.
7
+
8
+ class Line
9
+ INFINITY = 9999
10
+
11
+ LINE_TYPES = [
12
+ :BLANK,
13
+ :HEADING,
14
+ :LIST,
15
+ :PARAGRAPH,
16
+ :RULE,
17
+ :VERBATIM,
18
+ ]
19
+
20
+ # line type
21
+ attr_accessor :type
22
+
23
+ # The indentation nesting level
24
+ attr_accessor :level
25
+
26
+ # The contents
27
+ attr_accessor :text
28
+
29
+ # A prefix or parameter. For LIST lines, this is
30
+ # the text that introduced the list item (the label)
31
+ attr_accessor :param
32
+
33
+ # A flag. For list lines, this is the type of the list
34
+ attr_accessor :flag
35
+
36
+ # the number of leading spaces
37
+ attr_accessor :leading_spaces
38
+
39
+ # true if this line has been deleted from the list of lines
40
+ attr_accessor :deleted
41
+
42
+ def initialize(text)
43
+ @text = text.dup
44
+ @deleted = false
45
+
46
+ # expand tabs
47
+ 1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)} && $~ #`
48
+
49
+ # Strip trailing whitespace
50
+ @text.sub!(/\s+$/, '')
51
+
52
+ # and look for leading whitespace
53
+ if @text.length > 0
54
+ @text =~ /^(\s*)/
55
+ @leading_spaces = $1.length
56
+ else
57
+ @leading_spaces = INFINITY
58
+ end
59
+ end
60
+
61
+ # Return true if this line is blank
62
+ def blank?
63
+ @text.empty?
64
+ end
65
+
66
+ # stamp a line with a type, a level, a prefix, and a flag
67
+ def stamp(type, level, param="", flag=nil)
68
+ @type, @level, @param, @flag = type, level, param, flag
69
+ end
70
+
71
+ ##
72
+ # Strip off the leading margin
73
+
74
+ def strip_leading(size)
75
+ if @text.size > size
76
+ @text[0,size] = ""
77
+ else
78
+ @text = ""
79
+ end
80
+ end
81
+
82
+ def to_s
83
+ "#@type#@level: #@text"
84
+ end
85
+ end
86
+
87
+ ##
88
+ # A container for all the lines.
89
+
90
+ class Lines
91
+
92
+ include Enumerable
93
+
94
+ attr_reader :lines # :nodoc:
95
+
96
+ def initialize(lines)
97
+ @lines = lines
98
+ rewind
99
+ end
100
+
101
+ def empty?
102
+ @lines.size.zero?
103
+ end
104
+
105
+ def each
106
+ @lines.each do |line|
107
+ yield line unless line.deleted
108
+ end
109
+ end
110
+
111
+ # def [](index)
112
+ # @lines[index]
113
+ # end
114
+
115
+ def rewind
116
+ @nextline = 0
117
+ end
118
+
119
+ def next
120
+ begin
121
+ res = @lines[@nextline]
122
+ @nextline += 1 if @nextline < @lines.size
123
+ end while res and res.deleted and @nextline < @lines.size
124
+ res
125
+ end
126
+
127
+ def unget
128
+ @nextline -= 1
129
+ end
130
+
131
+ def delete(a_line)
132
+ a_line.deleted = true
133
+ end
134
+
135
+ def normalize
136
+ margin = @lines.collect{|l| l.leading_spaces}.min
137
+ margin = 0 if margin == :INFINITY
138
+ @lines.each {|line| line.strip_leading(margin) } if margin > 0
139
+ end
140
+
141
+ def as_text
142
+ @lines.map {|l| l.text}.join("\n")
143
+ end
144
+
145
+ def line_types
146
+ @lines.map {|l| l.type }
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+
@@ -0,0 +1,91 @@
1
+ # This class is MathML module wrapper.
2
+ # If MathML module can not be loaded, methods in this module return
3
+ # raw argument without modification.
4
+ require 'fileutils'
5
+
6
+ class MathMLWrapper
7
+
8
+ # Mathml library name
9
+ MATHML_NAME = [ "mathml", "math_ml" ]
10
+
11
+ # $LOAD_PATH/MATHML_NAME/MACRO_REL_PATH/* files are parsed as TeX macro
12
+ MACRO_REL_PATH = "macro"
13
+
14
+ @@mathml_required = false
15
+ @@macro_input_flag = false
16
+ @@macro_path = ''
17
+
18
+ def initialize
19
+
20
+ err_count = 0
21
+ if !@@mathml_required
22
+ MATHML_NAME.each{ |ml|
23
+ begin
24
+ require ml
25
+ @@macro_path = File.join(ml, MACRO_REL_PATH)
26
+ rescue LoadError
27
+ err_count = err_count + 1
28
+ end
29
+ }
30
+ if err_count < MATHML_NAME.size
31
+ @@mathml_required = true
32
+ else
33
+ raise LoadError,
34
+ " Error: \"#{MATHML_NAME.join('" or "')}\" library is not found\n" +
35
+ " in $LOAD_PATH=[#{$LOAD_PATH.join(',')}]\n\n"
36
+ end
37
+ end
38
+
39
+ if (@@mathml_required && !@@macro_input_flag)
40
+ @@mathml_formula_macro = MathML::LaTeX::Parser.new
41
+ @@macro_input_flag = true
42
+ $LOAD_PATH.each{ |lpath|
43
+ macro_files = Dir::glob(File.join(lpath, @@macro_path, "*"))
44
+ macro_files.each{ |mfile|
45
+ if File.file?(mfile)
46
+ File.open(mfile, "r" ) { |io|
47
+ if $DEBUG_RDOC
48
+ puts \
49
+ "\n##### Debug messages about \"#{__FILE__}\" #####",
50
+ " \"#{mfile}\" is loading as a TeX macro file.",
51
+ " Following macros have been included."
52
+ end
53
+ io.each{ |line|
54
+ line.chomp!
55
+ macroerrormsg = nil
56
+ begin
57
+ @@mathml_formula_macro.macro.parse(line)
58
+ rescue MathML::LaTeX::ParseError
59
+ macroerrormsg = $!.to_s
60
+ rescue
61
+ macroerrormsg = $!.to_s
62
+ end
63
+ if macroerrormsg
64
+ $stderr.puts "Warning: in #{mfile}, following TeX macro causes #{macroerrormsg.to_s}\n\n",
65
+ " #{line}\n\n"
66
+ else
67
+ if $DEBUG_RDOC && !(line.empty?) && !(line =~ /\s*\%/)
68
+ puts " #{line}"
69
+ end
70
+ end
71
+ }
72
+ }
73
+ end
74
+ }
75
+ }
76
+ end
77
+
78
+ end
79
+ def parse(formula, block=false)
80
+ return formula if !@@mathml_required
81
+ mathml_formula = @@mathml_formula_macro
82
+ begin
83
+ mathml_formula_str = mathml_formula.parse(formula, block).to_s
84
+ rescue MathML::LaTeX::ParseError
85
+ return formula, 1
86
+ rescue
87
+ return formula, 1
88
+ end
89
+ return mathml_formula_str, 0
90
+ end
91
+ end
@@ -0,0 +1,71 @@
1
+ require 'rdoc-f95/markup'
2
+
3
+ ##
4
+ # Handle common directives that can occur in a block of text:
5
+ #
6
+ # : include : filename
7
+
8
+ class RDocF95::Markup::PreProcess
9
+
10
+ def initialize(input_file_name, include_path)
11
+ @input_file_name = input_file_name
12
+ @include_path = include_path
13
+ end
14
+
15
+ ##
16
+ # Look for common options in a chunk of text. Options that we don't handle
17
+ # are passed back to our caller as |directive, param|
18
+
19
+ def handle(text)
20
+ text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do
21
+ prefix = $1
22
+ directive = $2.downcase
23
+ param = $3
24
+
25
+ case directive
26
+ when "include"
27
+ filename = param.split[0]
28
+ include_file(filename, prefix)
29
+
30
+ else
31
+ yield(directive, param)
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ ##
39
+ # Include a file, indenting it correctly.
40
+
41
+ def include_file(name, indent)
42
+ if full_name = find_include_file(name) then
43
+ content = File.open(full_name) {|f| f.read}
44
+ # strip leading '#'s, but only if all lines start with them
45
+ if content =~ /^[^#]/
46
+ content.gsub(/^/, indent)
47
+ else
48
+ content.gsub(/^#?/, indent)
49
+ end
50
+ else
51
+ $stderr.puts "Couldn't find file to include: '#{name}'"
52
+ ''
53
+ end
54
+ end
55
+
56
+ ##
57
+ # Look for the given file in the directory containing the current file,
58
+ # and then in each of the directories specified in the RDOC_INCLUDE path
59
+
60
+ def find_include_file(name)
61
+ to_search = [ File.dirname(@input_file_name) ].concat @include_path
62
+ to_search.each do |dir|
63
+ full_name = File.join(dir, name)
64
+ stat = File.stat(full_name) rescue next
65
+ return full_name if stat.readable?
66
+ end
67
+ nil
68
+ end
69
+
70
+ end
71
+
@@ -0,0 +1,16 @@
1
+ #!/usr/local/bin/ruby
2
+ # Illustration of a script to convert an RDoc-style file to a LaTeX
3
+ # document
4
+
5
+ require 'rdoc-f95/markup/simple_markup'
6
+ require 'rdoc-f95/markup/simple_markup/to_latex'
7
+
8
+ p = SM::SimpleMarkup.new
9
+ h = SM::ToLaTeX.new
10
+
11
+ #puts "\\documentclass{report}"
12
+ #puts "\\usepackage{tabularx}"
13
+ #puts "\\usepackage{parskip}"
14
+ #puts "\\begin{document}"
15
+ puts p.convert(ARGF.read, h)
16
+ #puts "\\end{document}"
@@ -0,0 +1,42 @@
1
+ # This program illustrates the basic use of the SimpleMarkup
2
+ # class. It extracts the first comment block from the
3
+ # simple_markup.rb file and converts it into HTML on
4
+ # standard output. Run it using
5
+ #
6
+ # % ruby sample.rb
7
+ #
8
+ # You should be in the sample/ directory when you do this,
9
+ # as it hardwires the path to the files it needs to require.
10
+ # This isn't necessary in the code you write once you've
11
+ # installed the package.
12
+ #
13
+ # For a better way of formatting code comment blocks (and more)
14
+ # see the rdoc package.
15
+ #
16
+
17
+ $:.unshift "../../.."
18
+
19
+ require 'rdoc-f95/markup/simple_markup'
20
+ require 'rdoc-f95/markup/simple_markup/to_html'
21
+
22
+ # Extract the comment block from the source file
23
+
24
+ input_string = ""
25
+
26
+ File.foreach("../simple_markup.rb") do |line|
27
+ break unless line.gsub!(/^\# ?/, '')
28
+ input_string << line
29
+ end
30
+
31
+ # Create a markup object
32
+ markup = SM::SimpleMarkup.new
33
+
34
+ # Attach it to an HTML formatter
35
+ h = SM::ToHtml.new
36
+
37
+ # And convert out comment block to html. Wrap it a body
38
+ # tag pair to let browsers view it
39
+
40
+ puts "<html><body>"
41
+ puts markup.convert(input_string, h)
42
+ puts "</body></html>"
@@ -0,0 +1,185 @@
1
+ require 'rdoc-f95/markup/formatter'
2
+ require 'rdoc-f95/markup/fragments'
3
+ require 'rdoc-f95/markup/inline'
4
+ require 'cgi'
5
+
6
+ class RDocF95::Markup
7
+
8
+ module Flow
9
+ P = Struct.new(:body)
10
+ VERB = Struct.new(:body)
11
+ RULE = Struct.new(:width)
12
+ class LIST
13
+ attr_reader :type, :contents
14
+ def initialize(type)
15
+ @type = type
16
+ @contents = []
17
+ end
18
+ def <<(stuff)
19
+ @contents << stuff
20
+ end
21
+ end
22
+ LI = Struct.new(:label, :body)
23
+ H = Struct.new(:level, :text)
24
+ end
25
+
26
+ class ToFlow < RDocF95::Markup::Formatter
27
+ LIST_TYPE_TO_HTML = {
28
+ :BULLET => [ "<ul>", "</ul>" ],
29
+ :NUMBER => [ "<ol>", "</ol>" ],
30
+ :UPPERALPHA => [ "<ol>", "</ol>" ],
31
+ :LOWERALPHA => [ "<ol>", "</ol>" ],
32
+ :LABELED => [ "<dl>", "</dl>" ],
33
+ :NOTE => [ "<table>", "</table>" ],
34
+ }
35
+
36
+ InlineTag = Struct.new(:bit, :on, :off)
37
+
38
+ def initialize
39
+ super
40
+
41
+ init_tags
42
+ end
43
+
44
+ ##
45
+ # Set up the standard mapping of attributes to HTML tags
46
+
47
+ def init_tags
48
+ @attr_tags = [
49
+ InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
50
+ InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(:TT), "<tt>", "</tt>"),
51
+ InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(:EM), "<em>", "</em>"),
52
+ ]
53
+ end
54
+
55
+ ##
56
+ # Add a new set of HTML tags for an attribute. We allow separate start and
57
+ # end tags for flexibility
58
+
59
+ def add_tag(name, start, stop)
60
+ @attr_tags << InlineTag.new(RDocF95::Markup::Attribute.bitmap_for(name), start, stop)
61
+ end
62
+
63
+ ##
64
+ # Given an HTML tag, decorate it with class information and the like if
65
+ # required. This is a no-op in the base class, but is overridden in HTML
66
+ # output classes that implement style sheets
67
+
68
+ def annotate(tag)
69
+ tag
70
+ end
71
+
72
+ ##
73
+ # Here's the client side of the visitor pattern
74
+
75
+ def start_accepting
76
+ @res = []
77
+ @list_stack = []
78
+ end
79
+
80
+ def end_accepting
81
+ @res
82
+ end
83
+
84
+ def accept_paragraph(am, fragment)
85
+ @res << Flow::P.new((convert_flow(am.flow(fragment.txt))))
86
+ end
87
+
88
+ def accept_verbatim(am, fragment)
89
+ @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt))))
90
+ end
91
+
92
+ def accept_rule(am, fragment)
93
+ size = fragment.param
94
+ size = 10 if size > 10
95
+ @res << Flow::RULE.new(size)
96
+ end
97
+
98
+ def accept_list_start(am, fragment)
99
+ @list_stack.push(@res)
100
+ list = Flow::LIST.new(fragment.type)
101
+ @res << list
102
+ @res = list
103
+ end
104
+
105
+ def accept_list_end(am, fragment)
106
+ @res = @list_stack.pop
107
+ end
108
+
109
+ def accept_list_item(am, fragment)
110
+ @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt)))
111
+ end
112
+
113
+ def accept_blank_line(am, fragment)
114
+ # @res << annotate("<p />") << "\n"
115
+ end
116
+
117
+ def accept_heading(am, fragment)
118
+ @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt)))
119
+ end
120
+
121
+ private
122
+
123
+ def on_tags(res, item)
124
+ attr_mask = item.turn_on
125
+ return if attr_mask.zero?
126
+
127
+ @attr_tags.each do |tag|
128
+ if attr_mask & tag.bit != 0
129
+ res << annotate(tag.on)
130
+ end
131
+ end
132
+ end
133
+
134
+ def off_tags(res, item)
135
+ attr_mask = item.turn_off
136
+ return if attr_mask.zero?
137
+
138
+ @attr_tags.reverse_each do |tag|
139
+ if attr_mask & tag.bit != 0
140
+ res << annotate(tag.off)
141
+ end
142
+ end
143
+ end
144
+
145
+ def convert_flow(flow)
146
+ res = ""
147
+ flow.each do |item|
148
+ case item
149
+ when String
150
+ res << convert_string(item)
151
+ when AttrChanger
152
+ off_tags(res, item)
153
+ on_tags(res, item)
154
+ when Special
155
+ res << convert_special(item)
156
+ else
157
+ raise "Unknown flow element: #{item.inspect}"
158
+ end
159
+ end
160
+ res
161
+ end
162
+
163
+ def convert_string(item)
164
+ CGI.escapeHTML(item)
165
+ end
166
+
167
+ def convert_special(special)
168
+ handled = false
169
+ Attribute.each_name_of(special.type) do |name|
170
+ method_name = "handle_special_#{name}"
171
+ if self.respond_to? method_name
172
+ special.text = send(method_name, special)
173
+ handled = true
174
+ end
175
+ end
176
+
177
+ raise "Unhandled special: #{special}" unless handled
178
+
179
+ special.text
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+