rdoc 3.1 → 6.3.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rdoc might be problematic. Click here for more details.

Files changed (247) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.rdoc +220 -0
  3. data/CVE-2013-0256.rdoc +49 -0
  4. data/ExampleMarkdown.md +37 -0
  5. data/ExampleRDoc.rdoc +208 -0
  6. data/Gemfile +12 -0
  7. data/History.rdoc +1666 -0
  8. data/LEGAL.rdoc +50 -0
  9. data/LICENSE.rdoc +57 -0
  10. data/README.rdoc +129 -0
  11. data/RI.rdoc +57 -0
  12. data/Rakefile +84 -81
  13. data/TODO.rdoc +59 -0
  14. data/bin/console +7 -0
  15. data/bin/setup +6 -0
  16. data/{bin → exe}/rdoc +11 -2
  17. data/exe/ri +12 -0
  18. data/lib/rdoc/alias.rb +1 -2
  19. data/lib/rdoc/anon_class.rb +3 -2
  20. data/lib/rdoc/any_method.rb +234 -40
  21. data/lib/rdoc/attr.rb +79 -11
  22. data/lib/rdoc/class_module.rb +443 -71
  23. data/lib/rdoc/code_object.rb +216 -20
  24. data/lib/rdoc/code_objects.rb +4 -21
  25. data/lib/rdoc/comment.rb +250 -0
  26. data/lib/rdoc/constant.rb +110 -9
  27. data/lib/rdoc/context/section.rb +232 -0
  28. data/lib/rdoc/context.rb +392 -172
  29. data/lib/rdoc/cross_reference.rb +202 -0
  30. data/lib/rdoc/encoding.rb +83 -28
  31. data/lib/rdoc/erb_partial.rb +19 -0
  32. data/lib/rdoc/erbio.rb +8 -3
  33. data/lib/rdoc/extend.rb +10 -0
  34. data/lib/rdoc/generator/darkfish.rb +507 -84
  35. data/lib/rdoc/generator/json_index.rb +300 -0
  36. data/lib/rdoc/generator/markup.rb +27 -74
  37. data/lib/rdoc/generator/pot/message_extractor.rb +68 -0
  38. data/lib/rdoc/generator/pot/po.rb +84 -0
  39. data/lib/rdoc/generator/pot/po_entry.rb +141 -0
  40. data/lib/rdoc/generator/pot.rb +98 -0
  41. data/lib/rdoc/generator/ri.rb +8 -62
  42. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
  43. data/lib/rdoc/generator/template/darkfish/_head.rhtml +22 -0
  44. data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +19 -0
  45. data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +9 -0
  46. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +15 -0
  47. data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +9 -0
  48. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +15 -0
  49. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +15 -0
  50. data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +12 -0
  51. data/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
  52. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +12 -0
  53. data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +11 -0
  54. data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +14 -0
  55. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
  56. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +18 -0
  57. data/lib/rdoc/generator/template/darkfish/class.rhtml +172 -0
  58. data/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
  59. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +639 -0
  60. data/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
  61. data/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
  62. data/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
  63. data/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
  64. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
  65. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
  66. data/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
  67. data/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
  68. data/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
  69. data/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
  70. data/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
  71. data/lib/rdoc/generator/template/darkfish/index.rhtml +18 -60
  72. data/lib/rdoc/generator/template/darkfish/js/darkfish.js +51 -83
  73. data/lib/rdoc/generator/template/darkfish/js/search.js +110 -0
  74. data/lib/rdoc/generator/template/darkfish/page.rhtml +18 -0
  75. data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +18 -0
  76. data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +62 -0
  77. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +58 -0
  78. data/lib/rdoc/generator/template/json_index/.document +1 -0
  79. data/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
  80. data/lib/rdoc/generator/template/json_index/js/searcher.js +229 -0
  81. data/lib/rdoc/generator.rb +24 -13
  82. data/lib/rdoc/ghost_method.rb +1 -2
  83. data/lib/rdoc/i18n/locale.rb +102 -0
  84. data/lib/rdoc/i18n/text.rb +126 -0
  85. data/lib/rdoc/i18n.rb +10 -0
  86. data/lib/rdoc/include.rb +5 -95
  87. data/lib/rdoc/known_classes.rb +5 -2
  88. data/lib/rdoc/markdown/entities.rb +2132 -0
  89. data/lib/rdoc/markdown/literals.kpeg +23 -0
  90. data/lib/rdoc/markdown/literals.rb +416 -0
  91. data/lib/rdoc/markdown.kpeg +1237 -0
  92. data/lib/rdoc/markdown.rb +16684 -0
  93. data/lib/rdoc/markup/attr_changer.rb +23 -0
  94. data/lib/rdoc/markup/attr_span.rb +36 -0
  95. data/lib/rdoc/markup/attribute_manager.rb +135 -62
  96. data/lib/rdoc/markup/attributes.rb +71 -0
  97. data/lib/rdoc/markup/blank_line.rb +1 -0
  98. data/lib/rdoc/markup/block_quote.rb +15 -0
  99. data/lib/rdoc/markup/document.rb +96 -9
  100. data/lib/rdoc/markup/formatter.rb +138 -25
  101. data/lib/rdoc/markup/hard_break.rb +32 -0
  102. data/lib/rdoc/markup/heading.rb +61 -2
  103. data/lib/rdoc/markup/include.rb +43 -0
  104. data/lib/rdoc/markup/indented_paragraph.rb +48 -0
  105. data/lib/rdoc/markup/list.rb +25 -4
  106. data/lib/rdoc/markup/list_item.rb +18 -4
  107. data/lib/rdoc/markup/paragraph.rb +15 -0
  108. data/lib/rdoc/markup/parser.rb +180 -88
  109. data/lib/rdoc/markup/pre_process.rb +183 -38
  110. data/lib/rdoc/markup/raw.rb +6 -5
  111. data/lib/rdoc/markup/regexp_handling.rb +41 -0
  112. data/lib/rdoc/markup/rule.rb +1 -0
  113. data/lib/rdoc/markup/table.rb +47 -0
  114. data/lib/rdoc/markup/to_ansi.rb +17 -7
  115. data/lib/rdoc/markup/to_bs.rb +5 -8
  116. data/lib/rdoc/markup/to_html.rb +238 -137
  117. data/lib/rdoc/markup/to_html_crossref.rb +125 -152
  118. data/lib/rdoc/markup/to_html_snippet.rb +285 -0
  119. data/lib/rdoc/markup/to_joined_paragraph.rb +47 -0
  120. data/lib/rdoc/markup/to_label.rb +75 -0
  121. data/lib/rdoc/markup/to_markdown.rb +192 -0
  122. data/lib/rdoc/markup/to_rdoc.rb +85 -15
  123. data/lib/rdoc/markup/to_table_of_contents.rb +89 -0
  124. data/lib/rdoc/markup/to_test.rb +2 -4
  125. data/lib/rdoc/markup/to_tt_only.rb +121 -0
  126. data/lib/rdoc/markup/verbatim.rb +39 -0
  127. data/lib/rdoc/markup.rb +388 -110
  128. data/lib/rdoc/meta_method.rb +1 -2
  129. data/lib/rdoc/method_attr.rb +87 -21
  130. data/lib/rdoc/mixin.rb +121 -0
  131. data/lib/rdoc/normal_class.rb +39 -10
  132. data/lib/rdoc/normal_module.rb +22 -7
  133. data/lib/rdoc/options.rb +613 -73
  134. data/lib/rdoc/parser/c.rb +621 -287
  135. data/lib/rdoc/parser/changelog.rb +335 -0
  136. data/lib/rdoc/parser/markdown.rb +24 -0
  137. data/lib/rdoc/parser/rd.rb +23 -0
  138. data/lib/rdoc/parser/ripper_state_lex.rb +590 -0
  139. data/lib/rdoc/parser/ruby.rb +1368 -762
  140. data/lib/rdoc/parser/ruby_tools.rb +42 -35
  141. data/lib/rdoc/parser/simple.rb +23 -11
  142. data/lib/rdoc/parser/text.rb +12 -0
  143. data/lib/rdoc/parser.rb +162 -89
  144. data/lib/rdoc/rd/block_parser.rb +1056 -0
  145. data/lib/rdoc/rd/block_parser.ry +639 -0
  146. data/lib/rdoc/rd/inline.rb +72 -0
  147. data/lib/rdoc/rd/inline_parser.rb +1208 -0
  148. data/lib/rdoc/rd/inline_parser.ry +593 -0
  149. data/lib/rdoc/rd.rb +100 -0
  150. data/lib/rdoc/rdoc.rb +208 -115
  151. data/lib/rdoc/require.rb +1 -2
  152. data/lib/rdoc/ri/driver.rb +734 -239
  153. data/lib/rdoc/ri/formatter.rb +1 -0
  154. data/lib/rdoc/ri/paths.rb +91 -48
  155. data/lib/rdoc/ri/store.rb +3 -261
  156. data/lib/rdoc/ri/task.rb +71 -0
  157. data/lib/rdoc/ri.rb +5 -2
  158. data/lib/rdoc/rubygems_hook.rb +246 -0
  159. data/lib/rdoc/servlet.rb +451 -0
  160. data/lib/rdoc/single_class.rb +14 -2
  161. data/lib/rdoc/stats/normal.rb +19 -12
  162. data/lib/rdoc/stats/quiet.rb +1 -0
  163. data/lib/rdoc/stats/verbose.rb +1 -0
  164. data/lib/rdoc/stats.rb +262 -104
  165. data/lib/rdoc/store.rb +979 -0
  166. data/lib/rdoc/task.rb +84 -44
  167. data/lib/rdoc/text.rb +117 -72
  168. data/lib/rdoc/token_stream.rb +73 -4
  169. data/lib/rdoc/tom_doc.rb +263 -0
  170. data/lib/rdoc/top_level.rb +111 -261
  171. data/lib/rdoc/version.rb +8 -0
  172. data/lib/rdoc.rb +127 -64
  173. data/man/ri.1 +247 -0
  174. data/rdoc.gemspec +249 -0
  175. metadata +171 -291
  176. data/.autotest +0 -16
  177. data/.document +0 -5
  178. data/History.txt +0 -594
  179. data/LICENSE.txt +0 -57
  180. data/Manifest.txt +0 -158
  181. data/README.txt +0 -45
  182. data/RI.txt +0 -58
  183. data/bin/ri +0 -5
  184. data/lib/rdoc/gauntlet.rb +0 -52
  185. data/lib/rdoc/generator/template/darkfish/classpage.rhtml +0 -296
  186. data/lib/rdoc/generator/template/darkfish/filepage.rhtml +0 -124
  187. data/lib/rdoc/generator/template/darkfish/js/jquery.js +0 -32
  188. data/lib/rdoc/generator/template/darkfish/js/quicksearch.js +0 -114
  189. data/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js +0 -10
  190. data/lib/rdoc/generator/template/darkfish/rdoc.css +0 -706
  191. data/lib/rdoc/markup/formatter_test_case.rb +0 -689
  192. data/lib/rdoc/markup/inline.rb +0 -137
  193. data/lib/rdoc/markup/text_formatter_test_case.rb +0 -116
  194. data/lib/rdoc/ruby_lex.rb +0 -1291
  195. data/lib/rdoc/ruby_token.rb +0 -416
  196. data/test/README +0 -1
  197. data/test/binary.dat +0 -0
  198. data/test/hidden.zip.txt +0 -1
  199. data/test/test.ja.rdoc +0 -10
  200. data/test/test.ja.txt +0 -8
  201. data/test/test.txt +0 -1
  202. data/test/test_attribute_manager.rb +0 -120
  203. data/test/test_rdoc_alias.rb +0 -13
  204. data/test/test_rdoc_any_method.rb +0 -126
  205. data/test/test_rdoc_attr.rb +0 -61
  206. data/test/test_rdoc_class_module.rb +0 -233
  207. data/test/test_rdoc_code_object.rb +0 -165
  208. data/test/test_rdoc_constant.rb +0 -15
  209. data/test/test_rdoc_context.rb +0 -370
  210. data/test/test_rdoc_encoding.rb +0 -166
  211. data/test/test_rdoc_generator_darkfish.rb +0 -119
  212. data/test/test_rdoc_generator_ri.rb +0 -76
  213. data/test/test_rdoc_include.rb +0 -96
  214. data/test/test_rdoc_markup.rb +0 -37
  215. data/test/test_rdoc_markup_attribute_manager.rb +0 -240
  216. data/test/test_rdoc_markup_document.rb +0 -51
  217. data/test/test_rdoc_markup_paragraph.rb +0 -9
  218. data/test/test_rdoc_markup_parser.rb +0 -1395
  219. data/test/test_rdoc_markup_pre_process.rb +0 -185
  220. data/test/test_rdoc_markup_raw.rb +0 -27
  221. data/test/test_rdoc_markup_to_ansi.rb +0 -328
  222. data/test/test_rdoc_markup_to_bs.rb +0 -341
  223. data/test/test_rdoc_markup_to_html.rb +0 -335
  224. data/test/test_rdoc_markup_to_html_crossref.rb +0 -169
  225. data/test/test_rdoc_markup_to_rdoc.rb +0 -327
  226. data/test/test_rdoc_method_attr.rb +0 -122
  227. data/test/test_rdoc_normal_class.rb +0 -17
  228. data/test/test_rdoc_normal_module.rb +0 -31
  229. data/test/test_rdoc_options.rb +0 -342
  230. data/test/test_rdoc_parser.rb +0 -83
  231. data/test/test_rdoc_parser_c.rb +0 -912
  232. data/test/test_rdoc_parser_ruby.rb +0 -1754
  233. data/test/test_rdoc_parser_simple.rb +0 -99
  234. data/test/test_rdoc_rdoc.rb +0 -164
  235. data/test/test_rdoc_require.rb +0 -25
  236. data/test/test_rdoc_ri_driver.rb +0 -846
  237. data/test/test_rdoc_ri_paths.rb +0 -43
  238. data/test/test_rdoc_ri_store.rb +0 -352
  239. data/test/test_rdoc_ruby_lex.rb +0 -23
  240. data/test/test_rdoc_stats.rb +0 -38
  241. data/test/test_rdoc_task.rb +0 -92
  242. data/test/test_rdoc_text.rb +0 -251
  243. data/test/test_rdoc_top_level.rb +0 -120
  244. data/test/xref_data.rb +0 -62
  245. data/test/xref_test_case.rb +0 -61
  246. data.tar.gz.sig +0 -3
  247. metadata.gz.sig +0 -0
@@ -0,0 +1,246 @@
1
+ # frozen_string_literal: true
2
+ require 'rubygems/user_interaction'
3
+ require 'fileutils'
4
+ require 'rdoc'
5
+
6
+ ##
7
+ # Gem::RDoc provides methods to generate RDoc and ri data for installed gems
8
+ # upon gem installation.
9
+ #
10
+ # This file is automatically required by RubyGems 1.9 and newer.
11
+
12
+ class RDoc::RubygemsHook
13
+
14
+ include Gem::UserInteraction
15
+ extend Gem::UserInteraction
16
+
17
+ @rdoc_version = nil
18
+ @specs = []
19
+
20
+ ##
21
+ # Force installation of documentation?
22
+
23
+ attr_accessor :force
24
+
25
+ ##
26
+ # Generate rdoc?
27
+
28
+ attr_accessor :generate_rdoc
29
+
30
+ ##
31
+ # Generate ri data?
32
+
33
+ attr_accessor :generate_ri
34
+
35
+ class << self
36
+
37
+ ##
38
+ # Loaded version of RDoc. Set by ::load_rdoc
39
+
40
+ attr_reader :rdoc_version
41
+
42
+ end
43
+
44
+ ##
45
+ # Post installs hook that generates documentation for each specification in
46
+ # +specs+
47
+
48
+ def self.generation_hook installer, specs
49
+ start = Time.now
50
+ types = installer.document
51
+
52
+ generate_rdoc = types.include? 'rdoc'
53
+ generate_ri = types.include? 'ri'
54
+
55
+ specs.each do |spec|
56
+ new(spec, generate_rdoc, generate_ri).generate
57
+ end
58
+
59
+ return unless generate_rdoc or generate_ri
60
+
61
+ duration = (Time.now - start).to_i
62
+ names = specs.map(&:name).join ', '
63
+
64
+ say "Done installing documentation for #{names} after #{duration} seconds"
65
+ end
66
+
67
+ ##
68
+ # Loads the RDoc generator
69
+
70
+ def self.load_rdoc
71
+ return if @rdoc_version
72
+
73
+ require_relative 'rdoc'
74
+
75
+ @rdoc_version = Gem::Version.new ::RDoc::VERSION
76
+ end
77
+
78
+ ##
79
+ # Creates a new documentation generator for +spec+. RDoc and ri data
80
+ # generation can be enabled or disabled through +generate_rdoc+ and
81
+ # +generate_ri+ respectively.
82
+ #
83
+ # Only +generate_ri+ is enabled by default.
84
+
85
+ def initialize spec, generate_rdoc = false, generate_ri = true
86
+ @doc_dir = spec.doc_dir
87
+ @force = false
88
+ @rdoc = nil
89
+ @spec = spec
90
+
91
+ @generate_rdoc = generate_rdoc
92
+ @generate_ri = generate_ri
93
+
94
+ @rdoc_dir = spec.doc_dir 'rdoc'
95
+ @ri_dir = spec.doc_dir 'ri'
96
+ end
97
+
98
+ ##
99
+ # Removes legacy rdoc arguments from +args+
100
+ #--
101
+ # TODO move to RDoc::Options
102
+
103
+ def delete_legacy_args args
104
+ args.delete '--inline-source'
105
+ args.delete '--promiscuous'
106
+ args.delete '-p'
107
+ args.delete '--one-file'
108
+ end
109
+
110
+ ##
111
+ # Generates documentation using the named +generator+ ("darkfish" or "ri")
112
+ # and following the given +options+.
113
+ #
114
+ # Documentation will be generated into +destination+
115
+
116
+ def document generator, options, destination
117
+ generator_name = generator
118
+
119
+ options = options.dup
120
+ options.exclude ||= [] # TODO maybe move to RDoc::Options#finish
121
+ options.setup_generator generator
122
+ options.op_dir = destination
123
+ options.finish
124
+
125
+ generator = options.generator.new @rdoc.store, options
126
+
127
+ @rdoc.options = options
128
+ @rdoc.generator = generator
129
+
130
+ say "Installing #{generator_name} documentation for #{@spec.full_name}"
131
+
132
+ FileUtils.mkdir_p options.op_dir
133
+
134
+ Dir.chdir options.op_dir do
135
+ begin
136
+ @rdoc.class.current = @rdoc
137
+ @rdoc.generator.generate
138
+ ensure
139
+ @rdoc.class.current = nil
140
+ end
141
+ end
142
+ end
143
+
144
+ ##
145
+ # Generates RDoc and ri data
146
+
147
+ def generate
148
+ return if @spec.default_gem?
149
+ return unless @generate_ri or @generate_rdoc
150
+
151
+ setup
152
+
153
+ options = nil
154
+
155
+ args = @spec.rdoc_options
156
+ args.concat @spec.source_paths
157
+ args.concat @spec.extra_rdoc_files
158
+
159
+ case config_args = Gem.configuration[:rdoc]
160
+ when String then
161
+ args = args.concat config_args.split(' ')
162
+ when Array then
163
+ args = args.concat config_args
164
+ end
165
+
166
+ delete_legacy_args args
167
+
168
+ Dir.chdir @spec.full_gem_path do
169
+ options = ::RDoc::Options.new
170
+ options.default_title = "#{@spec.full_name} Documentation"
171
+ options.parse args
172
+ end
173
+
174
+ options.quiet = !Gem.configuration.really_verbose
175
+
176
+ @rdoc = new_rdoc
177
+ @rdoc.options = options
178
+
179
+ store = RDoc::Store.new
180
+ store.encoding = options.encoding
181
+ store.dry_run = options.dry_run
182
+ store.main = options.main_page
183
+ store.title = options.title
184
+
185
+ @rdoc.store = store
186
+
187
+ say "Parsing documentation for #{@spec.full_name}"
188
+
189
+ Dir.chdir @spec.full_gem_path do
190
+ @rdoc.parse_files options.files
191
+ end
192
+
193
+ document 'ri', options, @ri_dir if
194
+ @generate_ri and (@force or not File.exist? @ri_dir)
195
+
196
+ document 'darkfish', options, @rdoc_dir if
197
+ @generate_rdoc and (@force or not File.exist? @rdoc_dir)
198
+ end
199
+
200
+ ##
201
+ # #new_rdoc creates a new RDoc instance. This method is provided only to
202
+ # make testing easier.
203
+
204
+ def new_rdoc # :nodoc:
205
+ ::RDoc::RDoc.new
206
+ end
207
+
208
+ ##
209
+ # Is rdoc documentation installed?
210
+
211
+ def rdoc_installed?
212
+ File.exist? @rdoc_dir
213
+ end
214
+
215
+ ##
216
+ # Removes generated RDoc and ri data
217
+
218
+ def remove
219
+ base_dir = @spec.base_dir
220
+
221
+ raise Gem::FilePermissionError, base_dir unless File.writable? base_dir
222
+
223
+ FileUtils.rm_rf @rdoc_dir
224
+ FileUtils.rm_rf @ri_dir
225
+ end
226
+
227
+ ##
228
+ # Is ri data installed?
229
+
230
+ def ri_installed?
231
+ File.exist? @ri_dir
232
+ end
233
+
234
+ ##
235
+ # Prepares the spec for documentation generation
236
+
237
+ def setup
238
+ self.class.load_rdoc
239
+
240
+ raise Gem::FilePermissionError, @doc_dir if
241
+ File.exist?(@doc_dir) and not File.writable?(@doc_dir)
242
+
243
+ FileUtils.mkdir_p @doc_dir unless File.exist? @doc_dir
244
+ end
245
+
246
+ end
@@ -0,0 +1,451 @@
1
+ # frozen_string_literal: true
2
+ require 'rdoc'
3
+ require 'erb'
4
+ require 'time'
5
+ require 'json'
6
+
7
+ begin
8
+ require 'webrick'
9
+ rescue LoadError
10
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
11
+ end
12
+
13
+ ##
14
+ # This is a WEBrick servlet that allows you to browse ri documentation.
15
+ #
16
+ # You can show documentation through either `ri --server` or, with RubyGems
17
+ # 2.0 or newer, `gem server`. For ri, the server runs on port 8214 by
18
+ # default. For RubyGems the server runs on port 8808 by default.
19
+ #
20
+ # You can use this servlet in your own project by mounting it on a WEBrick
21
+ # server:
22
+ #
23
+ # require 'webrick'
24
+ #
25
+ # server = WEBrick::HTTPServer.new Port: 8000
26
+ #
27
+ # server.mount '/', RDoc::Servlet
28
+ #
29
+ # If you want to mount the servlet some other place than the root, provide the
30
+ # base path when mounting:
31
+ #
32
+ # server.mount '/rdoc', RDoc::Servlet, '/rdoc'
33
+
34
+ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
35
+
36
+ @server_stores = Hash.new { |hash, server| hash[server] = {} }
37
+ @cache = Hash.new { |hash, store| hash[store] = {} }
38
+
39
+ ##
40
+ # Maps an asset type to its path on the filesystem
41
+
42
+ attr_reader :asset_dirs
43
+
44
+ ##
45
+ # An RDoc::Options instance used for rendering options
46
+
47
+ attr_reader :options
48
+
49
+ ##
50
+ # Creates an instance of this servlet that shares cached data between
51
+ # requests.
52
+
53
+ def self.get_instance server, *options # :nodoc:
54
+ stores = @server_stores[server]
55
+
56
+ new server, stores, @cache, *options
57
+ end
58
+
59
+ ##
60
+ # Creates a new WEBrick servlet.
61
+ #
62
+ # Use +mount_path+ when mounting the servlet somewhere other than /.
63
+ #
64
+ # Use +extra_doc_dirs+ for additional documentation directories.
65
+ #
66
+ # +server+ is provided automatically by WEBrick when mounting. +stores+ and
67
+ # +cache+ are provided automatically by the servlet.
68
+
69
+ def initialize server, stores, cache, mount_path = nil, extra_doc_dirs = []
70
+ super server
71
+
72
+ @cache = cache
73
+ @mount_path = mount_path
74
+ @extra_doc_dirs = extra_doc_dirs
75
+ @stores = stores
76
+
77
+ @options = RDoc::Options.new
78
+ @options.op_dir = '.'
79
+
80
+ darkfish_dir = nil
81
+
82
+ # HACK dup
83
+ $LOAD_PATH.each do |path|
84
+ darkfish_dir = File.join path, 'rdoc/generator/template/darkfish/'
85
+ next unless File.directory? darkfish_dir
86
+ @options.template_dir = darkfish_dir
87
+ break
88
+ end
89
+
90
+ @asset_dirs = {
91
+ :darkfish => darkfish_dir,
92
+ :json_index =>
93
+ File.expand_path('../generator/template/json_index/', __FILE__),
94
+ }
95
+ end
96
+
97
+ ##
98
+ # Serves the asset at the path in +req+ for +generator_name+ via +res+.
99
+
100
+ def asset generator_name, req, res
101
+ asset_dir = @asset_dirs[generator_name]
102
+
103
+ asset_path = File.join asset_dir, req.path
104
+
105
+ if_modified_since req, res, asset_path
106
+
107
+ res.body = File.read asset_path
108
+
109
+ res.content_type = case req.path
110
+ when /\.css\z/ then 'text/css'
111
+ when /\.js\z/ then 'application/javascript'
112
+ else 'application/octet-stream'
113
+ end
114
+ end
115
+
116
+ ##
117
+ # GET request entry point. Fills in +res+ for the path, etc. in +req+.
118
+
119
+ def do_GET req, res
120
+ req.path.sub!(/\A#{Regexp.escape @mount_path}/, '') if @mount_path
121
+
122
+ case req.path
123
+ when '/' then
124
+ root req, res
125
+ when '/js/darkfish.js', '/js/jquery.js', '/js/search.js',
126
+ %r%^/css/%, %r%^/images/%, %r%^/fonts/% then
127
+ asset :darkfish, req, res
128
+ when '/js/navigation.js', '/js/searcher.js' then
129
+ asset :json_index, req, res
130
+ when '/js/search_index.js' then
131
+ root_search req, res
132
+ else
133
+ show_documentation req, res
134
+ end
135
+ rescue WEBrick::HTTPStatus::NotFound => e
136
+ generator = generator_for RDoc::Store.new
137
+
138
+ not_found generator, req, res, e.message
139
+ rescue WEBrick::HTTPStatus::Status
140
+ raise
141
+ rescue => e
142
+ error e, req, res
143
+ end
144
+
145
+ ##
146
+ # Fills in +res+ with the class, module or page for +req+ from +store+.
147
+ #
148
+ # +path+ is relative to the mount_path and is used to determine the class,
149
+ # module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
150
+ # +generator+ is used to create the page.
151
+
152
+ def documentation_page store, generator, path, req, res
153
+ text_name = path.chomp '.html'
154
+ name = text_name.gsub '/', '::'
155
+
156
+ if klass = store.find_class_or_module(name) then
157
+ res.body = generator.generate_class klass
158
+ elsif page = store.find_text_page(name.sub(/_([^_]*)\z/, '.\1')) then
159
+ res.body = generator.generate_page page
160
+ elsif page = store.find_text_page(text_name.sub(/_([^_]*)\z/, '.\1')) then
161
+ res.body = generator.generate_page page
162
+ else
163
+ not_found generator, req, res
164
+ end
165
+ end
166
+
167
+ ##
168
+ # Creates the JSON search index on +res+ for the given +store+. +generator+
169
+ # must respond to \#json_index to build. +req+ is ignored.
170
+
171
+ def documentation_search store, generator, req, res
172
+ json_index = @cache[store].fetch :json_index do
173
+ @cache[store][:json_index] =
174
+ JSON.dump generator.json_index.build_index
175
+ end
176
+
177
+ res.content_type = 'application/javascript'
178
+ res.body = "var search_data = #{json_index}"
179
+ end
180
+
181
+ ##
182
+ # Returns the RDoc::Store and path relative to +mount_path+ for
183
+ # documentation at +path+.
184
+
185
+ def documentation_source path
186
+ _, source_name, path = path.split '/', 3
187
+
188
+ store = @stores[source_name]
189
+ return store, path if store
190
+
191
+ store = store_for source_name
192
+
193
+ store.load_all
194
+
195
+ @stores[source_name] = store
196
+
197
+ return store, path
198
+ end
199
+
200
+ ##
201
+ # Generates an error page for the +exception+ while handling +req+ on +res+.
202
+
203
+ def error exception, req, res
204
+ backtrace = exception.backtrace.join "\n"
205
+
206
+ res.content_type = 'text/html'
207
+ res.status = 500
208
+ res.body = <<-BODY
209
+ <!DOCTYPE html>
210
+ <html>
211
+ <head>
212
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
213
+
214
+ <title>Error - #{ERB::Util.html_escape exception.class}</title>
215
+
216
+ <link type="text/css" media="screen" href="#{@mount_path}/css/rdoc.css" rel="stylesheet">
217
+ </head>
218
+ <body>
219
+ <h1>Error</h1>
220
+
221
+ <p>While processing <code>#{ERB::Util.html_escape req.request_uri}</code> the
222
+ RDoc (#{ERB::Util.html_escape RDoc::VERSION}) server has encountered a
223
+ <code>#{ERB::Util.html_escape exception.class}</code>
224
+ exception:
225
+
226
+ <pre>#{ERB::Util.html_escape exception.message}</pre>
227
+
228
+ <p>Please report this to the
229
+ <a href="https://github.com/ruby/rdoc/issues">RDoc issues tracker</a>. Please
230
+ include the RDoc version, the URI above and exception class, message and
231
+ backtrace. If you're viewing a gem's documentation, include the gem name and
232
+ version. If you're viewing Ruby's documentation, include the version of ruby.
233
+
234
+ <p>Backtrace:
235
+
236
+ <pre>#{ERB::Util.html_escape backtrace}</pre>
237
+
238
+ </body>
239
+ </html>
240
+ BODY
241
+ end
242
+
243
+ ##
244
+ # Instantiates a Darkfish generator for +store+
245
+
246
+ def generator_for store
247
+ generator = RDoc::Generator::Darkfish.new store, @options
248
+ generator.file_output = false
249
+ generator.asset_rel_path = '..'
250
+
251
+ rdoc = RDoc::RDoc.new
252
+ rdoc.store = store
253
+ rdoc.generator = generator
254
+ rdoc.options = @options
255
+
256
+ @options.main_page = store.main
257
+ @options.title = store.title
258
+
259
+ generator
260
+ end
261
+
262
+ ##
263
+ # Handles the If-Modified-Since HTTP header on +req+ for +path+. If the
264
+ # file has not been modified a Not Modified response is returned. If the
265
+ # file has been modified a Last-Modified header is added to +res+.
266
+
267
+ def if_modified_since req, res, path = nil
268
+ last_modified = File.stat(path).mtime if path
269
+
270
+ res['last-modified'] = last_modified.httpdate
271
+
272
+ return unless ims = req['if-modified-since']
273
+
274
+ ims = Time.parse ims
275
+
276
+ unless ims < last_modified then
277
+ res.body = ''
278
+ raise WEBrick::HTTPStatus::NotModified
279
+ end
280
+ end
281
+
282
+ ##
283
+ # Returns an Array of installed documentation.
284
+ #
285
+ # Each entry contains the documentation name (gem name, 'Ruby
286
+ # Documentation', etc.), the path relative to the mount point, whether the
287
+ # documentation exists, the type of documentation (See RDoc::RI::Paths#each)
288
+ # and the filesystem to the RDoc::Store for the documentation.
289
+
290
+ def installed_docs
291
+ extra_counter = 0
292
+ ri_paths.map do |path, type|
293
+ store = RDoc::Store.new path, type
294
+ exists = File.exist? store.cache_path
295
+
296
+ case type
297
+ when :gem then
298
+ gem_path = path[%r%/([^/]*)/ri$%, 1]
299
+ [gem_path, "#{gem_path}/", exists, type, path]
300
+ when :system then
301
+ ['Ruby Documentation', 'ruby/', exists, type, path]
302
+ when :site then
303
+ ['Site Documentation', 'site/', exists, type, path]
304
+ when :home then
305
+ ['Home Documentation', 'home/', exists, type, path]
306
+ when :extra then
307
+ extra_counter += 1
308
+ store.load_cache if exists
309
+ title = store.title || "Extra Documentation"
310
+ [title, "extra-#{extra_counter}/", exists, type, path]
311
+ end
312
+ end
313
+ end
314
+
315
+ ##
316
+ # Returns a 404 page built by +generator+ for +req+ on +res+.
317
+
318
+ def not_found generator, req, res, message = nil
319
+ message ||= "The page <kbd>#{ERB::Util.h req.path}</kbd> was not found"
320
+ res.body = generator.generate_servlet_not_found message
321
+ res.status = 404
322
+ end
323
+
324
+ ##
325
+ # Enumerates the ri paths. See RDoc::RI::Paths#each
326
+
327
+ def ri_paths &block
328
+ RDoc::RI::Paths.each true, true, true, :all, *@extra_doc_dirs, &block #TODO: pass extra_dirs
329
+ end
330
+
331
+ ##
332
+ # Generates the root page on +res+. +req+ is ignored.
333
+
334
+ def root req, res
335
+ generator = RDoc::Generator::Darkfish.new nil, @options
336
+
337
+ res.body = generator.generate_servlet_root installed_docs
338
+
339
+ res.content_type = 'text/html'
340
+ end
341
+
342
+ ##
343
+ # Generates a search index for the root page on +res+. +req+ is ignored.
344
+
345
+ def root_search req, res
346
+ search_index = []
347
+ info = []
348
+
349
+ installed_docs.map do |name, href, exists, type, path|
350
+ next unless exists
351
+
352
+ search_index << name
353
+
354
+ case type
355
+ when :gem
356
+ gemspec = path.gsub(%r%/doc/([^/]*?)/ri$%,
357
+ '/specifications/\1.gemspec')
358
+
359
+ spec = Gem::Specification.load gemspec
360
+
361
+ path = spec.full_name
362
+ comment = spec.summary
363
+ when :system then
364
+ path = 'ruby'
365
+ comment = 'Documentation for the Ruby standard library'
366
+ when :site then
367
+ path = 'site'
368
+ comment = 'Documentation for non-gem libraries'
369
+ when :home then
370
+ path = 'home'
371
+ comment = 'Documentation from your home directory'
372
+ when :extra
373
+ comment = name
374
+ end
375
+
376
+ info << [name, '', path, '', comment]
377
+ end
378
+
379
+ index = {
380
+ :index => {
381
+ :searchIndex => search_index,
382
+ :longSearchIndex => search_index,
383
+ :info => info,
384
+ }
385
+ }
386
+
387
+ res.body = "var search_data = #{JSON.dump index};"
388
+ res.content_type = 'application/javascript'
389
+ end
390
+
391
+ ##
392
+ # Displays documentation for +req+ on +res+, whether that be HTML or some
393
+ # asset.
394
+
395
+ def show_documentation req, res
396
+ store, path = documentation_source req.path
397
+
398
+ if_modified_since req, res, store.cache_path
399
+
400
+ generator = generator_for store
401
+
402
+ case path
403
+ when nil, '', 'index.html' then
404
+ res.body = generator.generate_index
405
+ when 'table_of_contents.html' then
406
+ res.body = generator.generate_table_of_contents
407
+ when 'js/search_index.js' then
408
+ documentation_search store, generator, req, res
409
+ else
410
+ documentation_page store, generator, path, req, res
411
+ end
412
+ ensure
413
+ res.content_type ||= 'text/html'
414
+ end
415
+
416
+ ##
417
+ # Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
418
+
419
+ def store_for source_name
420
+ case source_name
421
+ when 'home' then
422
+ RDoc::Store.new RDoc::RI::Paths.home_dir, :home
423
+ when 'ruby' then
424
+ RDoc::Store.new RDoc::RI::Paths.system_dir, :system
425
+ when 'site' then
426
+ RDoc::Store.new RDoc::RI::Paths.site_dir, :site
427
+ when /\Aextra-(\d+)\z/ then
428
+ index = $1.to_i - 1
429
+ ri_dir = installed_docs[index][4]
430
+ RDoc::Store.new ri_dir, :extra
431
+ else
432
+ ri_dir, type = ri_paths.find do |dir, dir_type|
433
+ next unless dir_type == :gem
434
+
435
+ source_name == dir[%r%/([^/]*)/ri$%, 1]
436
+ end
437
+
438
+ raise WEBrick::HTTPStatus::NotFound,
439
+ "Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir
440
+
441
+ store = RDoc::Store.new ri_dir, type
442
+
443
+ return store if File.exist? store.cache_path
444
+
445
+ raise WEBrick::HTTPStatus::NotFound,
446
+ "Could not find documentation for \"#{ERB::Util.html_escape(source_name)}\". Please run `gem rdoc --ri gem_name`"
447
+
448
+ end
449
+ end
450
+
451
+ end
@@ -1,14 +1,26 @@
1
- require 'rdoc/class_module'
2
-
1
+ # frozen_string_literal: true
3
2
  ##
4
3
  # A singleton class
5
4
 
6
5
  class RDoc::SingleClass < RDoc::ClassModule
7
6
 
7
+ ##
8
8
  # Adds the superclass to the included modules.
9
+
9
10
  def ancestors
10
11
  superclass ? super + [superclass] : super
11
12
  end
12
13
 
14
+ def aref_prefix # :nodoc:
15
+ 'sclass'
16
+ end
17
+
18
+ ##
19
+ # The definition of this singleton class, <tt>class << MyClassName</tt>
20
+
21
+ def definition
22
+ "class << #{full_name}"
23
+ end
24
+
13
25
  end
14
26