We put rdoc stuff in the RDoc module to avoid namespace clutter.
ToDo: This isn‘t universally true.
(Japanese | English)
Here is a patch file to improve the RDoc analysis feature for Fortran 90/95 source codes. A patched package of RDoc source is also available.
Operation of the package has been verified with Ruby 1.8.2.
The latest version (Version $Name: rdoc-f95-20070227 $)
Archives of old versions
You have the following three ways for installation.
To use the patch file, follow the steps described below:
% tar -zxvf ruby-1.8.5-p12.tar.gz
% patch -p0 < rdoc-f95_ruby1.8.5-p12.patch
To install the patched RDoc package, follow the steps described below:
% tar -zxvf rdoc-f95.tgz
% cd rdoc-f95
% ruby install.rb
If rdoc is already installed, the original rdoc will be overritten.
Use —help option to show options and the directory to which rdoc is installed:
% ruby install.rb --help
Add following URL to sources.list of APT (/etc/apt/sources.list). You can use "ftp" protocol instead of "http".
deb http://www.gfd-dennou.org/library/cc-env/Linux/debian-dennou stable/
Install by APT commands.
% apt-get update % apt-get install rdoc-f95
This "rdoc-f95" package disables original "rdoc" package because "rdoc-f95" moves files of "rdoc" to diverted location. If you want to use original "rdoc" package, please remove "rdoc-f95". Then files of original "rdoc" package will be returned to proper location.
Following suggested packages enable you to use "diagram" and "mathml" options (see below).
% apt-get install graphviz libmathml-ruby
Set the environment variable PATH to include the directory where the execution program is installed, and RUBYLIB to include the directory where the libraries are installed.
Move to a directory where your Fortran 90/95 files exist, and execute the following command. HTML documents will be generated in doc directory.
% rdoc -U --ignore-case --inline-source
Files ending .f90, .F90, .f95, .F95 are parsed as Fortran 90/95 programs. All Fortran 90/95 programs in subdirectories are parsed recursively.
Just as in the original RDoc, files ending with .rb and .rbw are parsed as Ruby programs and files ending with .c, .cc, .cpp, .CC, .cxx are parsed as C programs.
With the option —op, the directory where HTML documents are generated can be changed. —title option sets title of HTML documents. When —all option is used, private subroutines, functions etc. in Fortran 90/95 programs are shown in HTML documents (for developers). If files or directories are specified as arguments (for example, "src/*.f90" or "test/"), the particular files are parsed. In the following example, files with suffix ".f90" in a directory "src/" and files in a directory "test/" are parsed.
% rdoc -U --ignore-case --inline-source \
--op rdoc --title "RDoc documentations" src/*.f90 test/
Alternatively, you can parse only a part of files by creating a ".document" file and writing names of the files and the directories to the file.
For more information, see README of original RDoc.
Refer to parsers/parse_f95.rb which explains parsed information, way of looking at documents, the format of comment blocks in Fortran 90/95 source code. If you use "—mathml" option (see below), refer to Generators::TexParser, too. For general information, see README of original RDoc .
This patch has been created for enhancing the Fortran 90/95 parser of RDoc . The Fortran 90/95 parse script parse_f95.rb is mainly modified, and other programs are also improved.
The original RDoc has been developed by Dave Thomas and is now maintained by Ryan Davis. The RDoc is available from the Ruby source code repository. See Ruby Repository Guide. For more information about RDoc, see README of original RDoc .
Differences to the original one are given below. Note that some differences were lost because this patch (2005/12/17 version) has been already included into the original RDoc package.
— #Enhancement of an analytical performance of Fortran 90/95 source codes :: # See parsers/parse_f95.rb for details.
#Modification of format of comment blocks :: # See parsers/parse_f95.rb for details. ++
| Addition of —ignore-case option : | In the Fortran 90/95 Standard, upper case letters are not distinguished from lower case letters, although original RDoc produces case-dependently cross-references of Class and Methods. When this options is specified, upper cases are not distinguished from lower cases. |
| Cross-reference of file names : | Cross-reference of file names is available as well as modules, subroutines, and so on. |
| Modification of —style option : | Original RDoc can not treat relative path stylesheet. Application of this patch modifies this function. |
| Conversion of TeX formula into MathML: | TeX formula can be converted into MathML format with —mathml option,
if MathML library for Ruby version 0.6b is installed. This library
is available from Bottega of Hiraku (JAPANESE only). See Generators::TexParser about
format.
*** Caution *** Documents generated with "—mathml" option are not displayed correctly according to browser and/or its setting. We have been confirmed that documents generated with "—mathml" option are displayed correctly with Mozilla Firefox and Internet Explorer (+ MathPlayer). See MathML Software - Browsers for other browsers. |
Some formats of comments in HTML document are changed to improve the analysis features. See parsers/parse_f95.rb for details.
The enhanced version of the RDoc Fortran 90/95 parser has been constructed on the premise of educational and academic usages only. For these uses, usage and modification of the resources withiout notification to the authors is permitted. Licence of the enhanced version of RDoc Fortran 90/95 parser conforms to that of original RDoc. See README of original RDoc .
When you publish your scientific/technological works using the enhanced version of RDoc Fortran 90/95 parser, we will be very glad if you cite our resources in the following way:
Morikawa,Y., Ishiwatari,M., Horinouchi,T., Odaka,M., Hayashi,Y.-Y., dcmodel: Numerical Model Project, 2007: Enhanced version of RDoc Fortran 90/95 parser, http://www.gfd-dennou.org/library/dcmodel/, GFD Dennou Club.
To contact us, please send an email to
.
| DOT_DOC_FILENAME | = | ".document" | Name of the dotfile that contains the description of files to be processed in the current directory | |
| KNOWN_CLASSES | = | { "rb_cObject" => "Object", "rb_cArray" => "Array", "rb_cBignum" => "Bignum", "rb_cClass" => "Class", "rb_cDir" => "Dir", "rb_cData" => "Data", "rb_cFalseClass" => "FalseClass", "rb_cFile" => "File", "rb_cFixnum" => "Fixnum", "rb_cFloat" => "Float", "rb_cHash" => "Hash", "rb_cInteger" => "Integer", "rb_cIO" => "IO", "rb_cModule" => "Module", "rb_cNilClass" => "NilClass", "rb_cNumeric" => "Numeric", "rb_cProc" => "Proc", "rb_cRange" => "Range", "rb_cRegexp" => "Regexp", "rb_cString" => "String", "rb_cSymbol" => "Symbol", "rb_cThread" => "Thread", "rb_cTime" => "Time", "rb_cTrueClass" => "TrueClass", "rb_cStruct" => "Struct", "rb_eException" => "Exception", "rb_eStandardError" => "StandardError", "rb_eSystemExit" => "SystemExit", "rb_eInterrupt" => "Interrupt", "rb_eSignal" => "Signal", "rb_eFatal" => "Fatal", "rb_eArgError" => "ArgError", "rb_eEOFError" => "EOFError", "rb_eIndexError" => "IndexError", "rb_eRangeError" => "RangeError", "rb_eIOError" => "IOError", "rb_eRuntimeError" => "RuntimeError", "rb_eSecurityError" => "SecurityError", "rb_eSystemCallError" => "SystemCallError", "rb_eTypeError" => "TypeError", "rb_eZeroDivError" => "ZeroDivError", "rb_eNotImpError" => "NotImpError", "rb_eNoMemError" => "NoMemError", "rb_eFloatDomainError" => "FloatDomainError", "rb_eScriptError" => "ScriptError", "rb_eNameError" => "NameError", "rb_eSyntaxError" => "SyntaxError", "rb_eLoadError" => "LoadError", "rb_mKernel" => "Kernel", "rb_mComparable" => "Comparable", "rb_mEnumerable" => "Enumerable", "rb_mPrecision" => "Precision", "rb_mErrno" => "Errno", "rb_mFileTest" => "FileTest", "rb_mGC" => "GC", "rb_mMath" => "Math", "rb_mProcess" => "Process" | ||
| GENERAL_MODIFIERS | = | [ 'nodoc' ].freeze | ||
| CLASS_MODIFIERS | = | GENERAL_MODIFIERS | ||
| ATTR_MODIFIERS | = | GENERAL_MODIFIERS | ||
| CONSTANT_MODIFIERS | = | GENERAL_MODIFIERS | ||
| METHOD_MODIFIERS | = | GENERAL_MODIFIERS + [ 'arg', 'args', 'yield', 'yields', 'notnew', 'not-new', 'not_new', 'doc' ] | ||
| DOT_DOC_FILENAME | = | ".document" | Name of the dotfile that contains the description of files to be processed in the current directory |
Given an array of flow items and an array of section names, extract those sections from the flow which have headings corresponding to a section name in the list. Return them in the order of names in the sections array.
# File usage.rb, line 165
165: def RDoc.extract_sections(flow, sections)
166: result = []
167: sections.each do |name|
168: name = name.downcase
169: copy_upto_level = nil
170:
171: flow.each do |item|
172: case item
173: when SM::Flow::H
174: if copy_upto_level && item.level >= copy_upto_level
175: copy_upto_level = nil
176: else
177: if item.text.downcase == name
178: result << item
179: copy_upto_level = item.level
180: end
181: end
182: else
183: if copy_upto_level
184: result << item
185: end
186: end
187: end
188: end
189: if result.empty?
190: puts "Note to developer: requested section(s) [#{sections.join(', ')}] " +
191: "not found"
192: result = flow
193: end
194: result
195: end
Given an array of flow items and an array of section names, extract those sections from the flow which have headings corresponding to a section name in the list. Return them in the order of names in the sections array.
# File doc-tmp/rdoc/usage.rb, line 165
165: def RDoc.extract_sections(flow, sections)
166: result = []
167: sections.each do |name|
168: name = name.downcase
169: copy_upto_level = nil
170:
171: flow.each do |item|
172: case item
173: when SM::Flow::H
174: if copy_upto_level && item.level >= copy_upto_level
175: copy_upto_level = nil
176: else
177: if item.text.downcase == name
178: result << item
179: copy_upto_level = item.level
180: end
181: end
182: else
183: if copy_upto_level
184: result << item
185: end
186: end
187: end
188: end
189: if result.empty?
190: puts "Note to developer: requested section(s) [#{sections.join(', ')}] " +
191: "not found"
192: result = flow
193: end
194: result
195: end
# File usage.rb, line 141
141: def RDoc.find_comment(file)
142: catch(:exit) do
143: # skip leading blank lines
144: 0 while (line = gets(file)) && (line =~ /^\s*$/)
145:
146: comment = []
147: while line && line =~ /^\s*#/
148: comment << line
149: line = gets(file)
150: end
151:
152: 0 while line && (line = gets(file))
153: return no_comment if comment.empty?
154: return comment.join
155: end
156: end
# File doc-tmp/rdoc/usage.rb, line 141
141: def RDoc.find_comment(file)
142: catch(:exit) do
143: # skip leading blank lines
144: 0 while (line = gets(file)) && (line =~ /^\s*$/)
145:
146: comment = []
147: while line && line =~ /^\s*#/
148: comment << line
149: line = gets(file)
150: end
151:
152: 0 while line && (line = gets(file))
153: return no_comment if comment.empty?
154: return comment.join
155: end
156: end
Find the first comment in the file (that isn‘t a shebang line) If the file doesn‘t start with a comment, report the fact and return empty string
# File usage.rb, line 133
133: def RDoc.gets(file)
134: if (line = file.gets) && (line =~ /^#!/) # shebang
135: throw :exit, find_comment(file)
136: else
137: line
138: end
139: end
Find the first comment in the file (that isn‘t a shebang line) If the file doesn‘t start with a comment, report the fact and return empty string
# File doc-tmp/rdoc/usage.rb, line 133
133: def RDoc.gets(file)
134: if (line = file.gets) && (line =~ /^#!/) # shebang
135: throw :exit, find_comment(file)
136: else
137: line
138: end
139: end
Report the fact that no doc comment count be found
# File usage.rb, line 199
199: def RDoc.no_comment
200: $stderr.puts "No usage information available for this program"
201: ""
202: end
Report the fact that no doc comment count be found
# File doc-tmp/rdoc/usage.rb, line 199
199: def RDoc.no_comment
200: $stderr.puts "No usage information available for this program"
201: ""
202: end
Display usage information from the comment at the top of the file. String arguments identify specific sections of the comment to display. An optional integer first argument specifies the exit status (defaults to 0)
# File doc-tmp/rdoc/usage.rb, line 81
81: def RDoc.usage(*args)
82: exit_code = 0
83:
84: if args.size > 0
85: status = args[0]
86: if status.respond_to?(:to_int)
87: exit_code = status.to_int
88: args.shift
89: end
90: end
91:
92: # display the usage and exit with the given code
93: usage_no_exit(*args)
94: exit(exit_code)
95: end
Display usage information from the comment at the top of the file. String arguments identify specific sections of the comment to display. An optional integer first argument specifies the exit status (defaults to 0)
# File usage.rb, line 81
81: def RDoc.usage(*args)
82: exit_code = 0
83:
84: if args.size > 0
85: status = args[0]
86: if status.respond_to?(:to_int)
87: exit_code = status.to_int
88: args.shift
89: end
90: end
91:
92: # display the usage and exit with the given code
93: usage_no_exit(*args)
94: exit(exit_code)
95: end
Display usage
# File usage.rb, line 98
98: def RDoc.usage_no_exit(*args)
99: main_program_file, = caller[-1].split(/:\d+/, 2)
100: comment = File.open(main_program_file) do |file|
101: find_comment(file)
102: end
103:
104: comment = comment.gsub(/^\s*#/, '')
105:
106: markup = SM::SimpleMarkup.new
107: flow_convertor = SM::ToFlow.new
108:
109: flow = markup.convert(comment, flow_convertor)
110:
111: format = "plain"
112:
113: unless args.empty?
114: flow = extract_sections(flow, args)
115: end
116:
117: options = RI::Options.instance
118: if args = ENV["RI"]
119: options.parse(args.split)
120: end
121: formatter = options.formatter.new(options, "")
122: formatter.display_flow(flow)
123: end
Display usage
# File doc-tmp/rdoc/usage.rb, line 98
98: def RDoc.usage_no_exit(*args)
99: main_program_file, = caller[-1].split(/:\d+/, 2)
100: comment = File.open(main_program_file) do |file|
101: find_comment(file)
102: end
103:
104: comment = comment.gsub(/^\s*#/, '')
105:
106: markup = SM::SimpleMarkup.new
107: flow_convertor = SM::ToFlow.new
108:
109: flow = markup.convert(comment, flow_convertor)
110:
111: format = "plain"
112:
113: unless args.empty?
114: flow = extract_sections(flow, args)
115: end
116:
117: options = RI::Options.instance
118: if args = ENV["RI"]
119: options.parse(args.split)
120: end
121: formatter = options.formatter.new(options, "")
122: formatter.display_flow(flow)
123: end