summaryrefslogtreecommitdiff
path: root/lib/rdoc
diff options
context:
space:
mode:
author(no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-01-06 05:59:32 +0000
committer(no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-01-06 05:59:32 +0000
commit52d96403d62f56fb6fd37d97c6b8c112662a0f4d (patch)
tree9976af12525b68f3e8205d7d8837a57d52bfffad /lib/rdoc
parent9a826fff233de78476a2bbccd63338056781ffa5 (diff)
This commit was manufactured by cvs2svn to create branch 'ruby_1_8'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@5387 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc')
-rw-r--r--lib/rdoc/ri/ri_display.rb254
-rw-r--r--lib/rdoc/ri/ri_driver.rb122
2 files changed, 376 insertions, 0 deletions
diff --git a/lib/rdoc/ri/ri_display.rb b/lib/rdoc/ri/ri_display.rb
new file mode 100644
index 0000000000..6899fe165a
--- /dev/null
+++ b/lib/rdoc/ri/ri_display.rb
@@ -0,0 +1,254 @@
+require 'rdoc/ri/ri_util'
+require 'rdoc/ri/ri_formatter'
+require 'rdoc/ri/ri_options'
+
+
+# This is a kind of 'flag' module. If you want to write your
+# own 'ri' display module (perhaps because you'r writing
+# an IDE or somesuch beast), you simply write a class
+# which implements the various 'display' methods in 'DefaultDisplay',
+# and include the 'RiDisplay' module in that class.
+#
+# To access your class from the command line, you can do
+#
+# ruby -r <your source file> ../ri ....
+#
+# If folks _really_ want to do this from the command line,
+# I'll build an option in
+
+module RiDisplay
+ @@display_class = nil
+
+ def RiDisplay.append_features(display_class)
+ @@display_class = display_class
+ end
+
+ def RiDisplay.new(*args)
+ @@display_class.new(*args)
+ end
+end
+
+######################################################################
+#
+# A paging display module. Uses the ri_formatter class to do the
+# actual presentation
+#
+
+class DefaultDisplay
+
+ include RiDisplay
+
+ def initialize(options)
+ @options = options
+ @formatter = @options.formatter.new(@options, " ")
+ end
+
+
+ ######################################################################
+
+ def display_usage
+ page do
+ RI::Options::OptionList.usage(short_form=true)
+ end
+ end
+
+
+ ######################################################################
+
+ def display_method_info(method)
+ page do
+ @formatter.draw_line(method.full_name)
+ display_params(method)
+ @formatter.draw_line
+ display_flow(method.comment)
+ if method.aliases && !method.aliases.empty?
+ @formatter.blankline
+ aka = "(also known as "
+ aka << method.aliases.map {|a| a.name }.join(", ")
+ aka << ")"
+ @formatter.wrap(aka)
+ end
+ end
+ end
+
+ ######################################################################
+
+ def display_class_info(klass, ri_reader)
+ page do
+ superclass = klass.superclass_string
+
+ if superclass
+ superclass = " < " + superclass
+ else
+ superclass = ""
+ end
+
+ @formatter.draw_line(klass.display_name + ": " +
+ klass.full_name + superclass)
+
+ display_flow(klass.comment)
+ @formatter.draw_line
+
+ unless klass.includes.empty?
+ @formatter.blankline
+ @formatter.display_heading("Includes:", 2, "")
+ incs = []
+ klass.includes.each do |inc|
+ inc_desc = ri_reader.find_class_by_name(inc.name)
+ if inc_desc
+ str = inc.name + "("
+ str << inc_desc.instance_methods.map{|m| m.name}.join(", ")
+ str << ")"
+ incs << str
+ else
+ incs << inc.name
+ end
+ end
+ @formatter.wrap(incs.sort.join(', '))
+ end
+
+ unless klass.constants.empty?
+ @formatter.blankline
+ @formatter.display_heading("Constants:", 2, "")
+ len = 0
+ klass.constants.each { |c| len = c.name.length if c.name.length > len }
+ len += 2
+ klass.constants.each do |c|
+ @formatter.wrap(c.value,
+ @formatter.indent+((c.name+":").ljust(len)))
+ end
+ end
+
+ unless klass.class_methods.empty?
+ @formatter.blankline
+ @formatter.display_heading("Class methods:", 2, "")
+ @formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', '))
+ end
+
+ unless klass.instance_methods.empty?
+ @formatter.blankline
+ @formatter.display_heading("Instance methods:", 2, "")
+ @formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', '))
+ end
+
+ unless klass.attributes.empty?
+ @formatter.blankline
+ @formatter.wrap("Attributes:", "")
+ @formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', '))
+ end
+ end
+ end
+
+ ######################################################################
+
+ # Display a list of method names
+
+ def display_method_list(methods)
+ page do
+ puts "More than one method matched your request. You can refine"
+ puts "your search by asking for information on one of:\n\n"
+ @formatter.wrap(methods.map {|m| m.full_name} .join(", "))
+ end
+ end
+
+ ######################################################################
+
+ def display_class_list(namespaces)
+ page do
+ puts "More than one class or module matched your request. You can refine"
+ puts "your search by asking for information on one of:\n\n"
+ @formatter.wrap(namespaces.map {|m| m.full_name}.join(", "))
+ end
+ end
+
+ ######################################################################
+
+ def list_known_classes(classes)
+ if classes.empty?
+ puts "Before using ri, you need to generate documentation"
+ puts "using 'rdoc' with the --ri option"
+ else
+ page do
+ @formatter.draw_line("Known classes and modules")
+ @formatter.blankline
+ @formatter.wrap(classes.sort.join(", "))
+ end
+ end
+ end
+
+ ######################################################################
+
+ private
+
+ ######################################################################
+
+ def page
+ setup_pager
+ begin
+ yield
+ page_output
+ ensure
+ STDOUT.reopen(@save_stdout) if @save_stdout
+ end
+ end
+
+ ######################################################################
+
+ def setup_pager
+ unless @options.use_stdout
+ require 'tempfile'
+
+ @save_stdout = STDOUT.clone
+ STDOUT.reopen(Tempfile.new("ri_"))
+ end
+ end
+
+ ######################################################################
+
+ def page_output
+ unless @options.use_stdout
+ path = STDOUT.path
+ STDOUT.reopen(@save_stdout)
+ @save_stdout = nil
+ paged = false
+ for pager in [ ENV['PAGER'], "less", "more <", 'pager' ].compact.uniq
+ if system("#{pager} #{path}")
+ paged = true
+ break
+ end
+ end
+ if !paged
+ @options.use_stdout = true
+ puts File.read(path)
+ end
+ end
+ end
+
+ ######################################################################
+
+ def display_params(method)
+
+ params = method.params
+
+ if params[0,1] == "("
+ if method.is_singleton
+ params = method.full_name + params
+ else
+ params = method.name + params
+ end
+ end
+ params.split(/\n/).each {|p| @formatter.wrap(p) }
+ end
+
+ ######################################################################
+
+ def display_flow(flow)
+ if !flow || flow.empty?
+ @formatter.wrap("(no description...)")
+ else
+ @formatter.display_flow(flow)
+ end
+ end
+
+
+end # class RiDisplay
diff --git a/lib/rdoc/ri/ri_driver.rb b/lib/rdoc/ri/ri_driver.rb
new file mode 100644
index 0000000000..0ca3b4c224
--- /dev/null
+++ b/lib/rdoc/ri/ri_driver.rb
@@ -0,0 +1,122 @@
+require 'rdoc/ri/ri_paths'
+require 'rdoc/ri/ri_cache'
+require 'rdoc/ri/ri_util'
+require 'rdoc/ri/ri_reader'
+require 'rdoc/ri/ri_formatter'
+require 'rdoc/ri/ri_options'
+
+
+######################################################################
+
+class RiDriver
+
+ def initialize
+ @options = RI::Options.instance
+ @options.parse
+ paths = @options.paths || RI::Paths::PATH
+ if paths.empty?
+ $stderr.puts "No ri documentation found in:"
+ [ RI::Paths::SYSDIR, RI::Paths::SITEDIR, RI::Paths::HOMEDIR].each do |d|
+ $stderr.puts " #{d}"
+ end
+ $stderr.puts "\nWas rdoc run to create documentation?"
+ exit 1
+ end
+ @ri_reader = RI::RiReader.new(RI::RiCache.new(paths))
+ @display = @options.displayer
+ end
+
+
+
+ ######################################################################
+
+ # If the list of matching methods contains exactly one entry, or
+ # if it contains an entry that exactly matches the requested method,
+ # then display that entry, otherwise display the list of
+ # matching method names
+
+ def report_method_stuff(requested_method_name, methods)
+ if methods.size == 1
+ method = @ri_reader.get_method(methods[0])
+ @display.display_method_info(method)
+ else
+ entries = methods.find_all {|m| m.name == requested_method_name}
+ if entries.size == 1
+ method = @ri_reader.get_method(entries[0])
+ @display.display_method_info(method)
+ else
+ @display.display_method_list(methods)
+ end
+ end
+ end
+
+ ######################################################################
+
+ def report_class_stuff(requested_class_name, namespaces)
+ if namespaces.size == 1
+ klass = @ri_reader.get_class(namespaces[0])
+ @display.display_class_info(klass, @ri_reader)
+ else
+ entries = namespaces.find_all {|m| m.full_name == requested_class_name}
+ if entries.size == 1
+ klass = @ri_reader.get_class(entries[0])
+ @display.display_class_info(klass, @ri_reader)
+ else
+ @display.display_class_list(namespaces)
+ end
+ end
+ end
+
+ ######################################################################
+
+
+ def get_info_for(arg)
+ desc = NameDescriptor.new(arg)
+
+ namespaces = @ri_reader.top_level_namespace
+
+ for class_name in desc.class_names
+ namespaces = @ri_reader.lookup_namespace_in(class_name, namespaces)
+ if namespaces.empty?
+ raise RiError.new("Nothing known about #{arg}")
+ end
+ end
+
+ if desc.method_name.nil?
+ report_class_stuff(desc.class_names.join('::'), namespaces)
+ else
+ methods = @ri_reader.find_methods(desc.method_name,
+ desc.is_class_method,
+ namespaces)
+
+ if methods.empty?
+ raise RiError.new("Nothing known about #{arg}")
+ else
+ report_method_stuff(desc.method_name, methods)
+ end
+ end
+ end
+
+ ######################################################################
+
+ def process_args
+ if @options.list_classes
+ classes = @ri_reader.class_names
+ @display.list_known_classes(classes)
+ else
+ if ARGV.size.zero?
+ @display.display_usage
+ else
+ begin
+ ARGV.each do |arg|
+ get_info_for(arg)
+ end
+ rescue RiError => e
+ $stderr.puts(e.message)
+ exit(1)
+ end
+ end
+ end
+ end
+
+end # class RiDriver