/tools/Ruby/lib/ruby/1.8/rdoc/ri/ri_display.rb

http://github.com/agross/netopenspace · Ruby · 255 lines · 177 code · 47 blank · 31 comment · 15 complexity · 9b9c2957f40f1264c88d54ddd9e53fbc MD5 · raw file

  1. require 'rdoc/ri/ri_util'
  2. require 'rdoc/ri/ri_formatter'
  3. require 'rdoc/ri/ri_options'
  4. # This is a kind of 'flag' module. If you want to write your
  5. # own 'ri' display module (perhaps because you'r writing
  6. # an IDE or somesuch beast), you simply write a class
  7. # which implements the various 'display' methods in 'DefaultDisplay',
  8. # and include the 'RiDisplay' module in that class.
  9. #
  10. # To access your class from the command line, you can do
  11. #
  12. # ruby -r <your source file> ../ri ....
  13. #
  14. # If folks _really_ want to do this from the command line,
  15. # I'll build an option in
  16. module RiDisplay
  17. @@display_class = nil
  18. def RiDisplay.append_features(display_class)
  19. @@display_class = display_class
  20. end
  21. def RiDisplay.new(*args)
  22. @@display_class.new(*args)
  23. end
  24. end
  25. ######################################################################
  26. #
  27. # A paging display module. Uses the ri_formatter class to do the
  28. # actual presentation
  29. #
  30. class DefaultDisplay
  31. include RiDisplay
  32. def initialize(options)
  33. @options = options
  34. @formatter = @options.formatter.new(@options, " ")
  35. end
  36. ######################################################################
  37. def display_usage
  38. page do
  39. RI::Options::OptionList.usage(short_form=true)
  40. end
  41. end
  42. ######################################################################
  43. def display_method_info(method)
  44. page do
  45. @formatter.draw_line(method.full_name)
  46. display_params(method)
  47. @formatter.draw_line
  48. display_flow(method.comment)
  49. if method.aliases && !method.aliases.empty?
  50. @formatter.blankline
  51. aka = "(also known as "
  52. aka << method.aliases.map {|a| a.name }.join(", ")
  53. aka << ")"
  54. @formatter.wrap(aka)
  55. end
  56. end
  57. end
  58. ######################################################################
  59. def display_class_info(klass, ri_reader)
  60. page do
  61. superclass = klass.superclass_string
  62. if superclass
  63. superclass = " < " + superclass
  64. else
  65. superclass = ""
  66. end
  67. @formatter.draw_line(klass.display_name + ": " +
  68. klass.full_name + superclass)
  69. display_flow(klass.comment)
  70. @formatter.draw_line
  71. unless klass.includes.empty?
  72. @formatter.blankline
  73. @formatter.display_heading("Includes:", 2, "")
  74. incs = []
  75. klass.includes.each do |inc|
  76. inc_desc = ri_reader.find_class_by_name(inc.name)
  77. if inc_desc
  78. str = inc.name + "("
  79. str << inc_desc.instance_methods.map{|m| m.name}.join(", ")
  80. str << ")"
  81. incs << str
  82. else
  83. incs << inc.name
  84. end
  85. end
  86. @formatter.wrap(incs.sort.join(', '))
  87. end
  88. unless klass.constants.empty?
  89. @formatter.blankline
  90. @formatter.display_heading("Constants:", 2, "")
  91. len = 0
  92. klass.constants.each { |c| len = c.name.length if c.name.length > len }
  93. len += 2
  94. klass.constants.each do |c|
  95. @formatter.wrap(c.value,
  96. @formatter.indent+((c.name+":").ljust(len)))
  97. end
  98. end
  99. unless klass.class_methods.empty?
  100. @formatter.blankline
  101. @formatter.display_heading("Class methods:", 2, "")
  102. @formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', '))
  103. end
  104. unless klass.instance_methods.empty?
  105. @formatter.blankline
  106. @formatter.display_heading("Instance methods:", 2, "")
  107. @formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', '))
  108. end
  109. unless klass.attributes.empty?
  110. @formatter.blankline
  111. @formatter.wrap("Attributes:", "")
  112. @formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', '))
  113. end
  114. end
  115. end
  116. ######################################################################
  117. # Display a list of method names
  118. def display_method_list(methods)
  119. page do
  120. puts "More than one method matched your request. You can refine"
  121. puts "your search by asking for information on one of:\n\n"
  122. @formatter.wrap(methods.map {|m| m.full_name} .join(", "))
  123. end
  124. end
  125. ######################################################################
  126. def display_class_list(namespaces)
  127. page do
  128. puts "More than one class or module matched your request. You can refine"
  129. puts "your search by asking for information on one of:\n\n"
  130. @formatter.wrap(namespaces.map {|m| m.full_name}.join(", "))
  131. end
  132. end
  133. ######################################################################
  134. def list_known_classes(classes)
  135. if classes.empty?
  136. warn_no_database
  137. else
  138. page do
  139. @formatter.draw_line("Known classes and modules")
  140. @formatter.blankline
  141. @formatter.wrap(classes.sort.join(", "))
  142. end
  143. end
  144. end
  145. ######################################################################
  146. def list_known_names(names)
  147. if names.empty?
  148. warn_no_database
  149. else
  150. page do
  151. names.each {|n| @formatter.raw_print_line(n)}
  152. end
  153. end
  154. end
  155. ######################################################################
  156. private
  157. ######################################################################
  158. def page
  159. return yield unless pager = setup_pager
  160. begin
  161. save_stdout = STDOUT.clone
  162. STDOUT.reopen(pager)
  163. yield
  164. ensure
  165. STDOUT.reopen(save_stdout)
  166. save_stdout.close
  167. pager.close
  168. end
  169. end
  170. ######################################################################
  171. def setup_pager
  172. unless @options.use_stdout
  173. for pager in [ ENV['PAGER'], "less", "more", 'pager' ].compact.uniq
  174. return IO.popen(pager, "w") rescue nil
  175. end
  176. @options.use_stdout = true
  177. nil
  178. end
  179. end
  180. ######################################################################
  181. def display_params(method)
  182. params = method.params
  183. if params[0,1] == "("
  184. if method.is_singleton
  185. params = method.full_name + params
  186. else
  187. params = method.name + params
  188. end
  189. end
  190. params.split(/\n/).each do |p|
  191. @formatter.wrap(p)
  192. @formatter.break_to_newline
  193. end
  194. end
  195. ######################################################################
  196. def display_flow(flow)
  197. if !flow || flow.empty?
  198. @formatter.wrap("(no description...)")
  199. else
  200. @formatter.display_flow(flow)
  201. end
  202. end
  203. ######################################################################
  204. def warn_no_database
  205. puts "Before using ri, you need to generate documentation"
  206. puts "using 'rdoc' with the --ri option"
  207. end
  208. end # class RiDisplay