rdoc 8.0.0 → 8.1.0
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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -3
- data/RI.md +75 -75
- data/exe/rdoc +2 -2
- data/lib/rdoc/code_object/alias.rb +71 -69
- data/lib/rdoc/code_object/any_method.rb +305 -303
- data/lib/rdoc/code_object/attr.rb +150 -148
- data/lib/rdoc/code_object/class_module.rb +798 -792
- data/lib/rdoc/code_object/constant.rb +175 -173
- data/lib/rdoc/code_object/context/section.rb +142 -138
- data/lib/rdoc/code_object/context.rb +926 -958
- data/lib/rdoc/code_object/extend.rb +7 -5
- data/lib/rdoc/code_object/include.rb +7 -5
- data/lib/rdoc/code_object/method_attr.rb +326 -319
- data/lib/rdoc/code_object/mixin.rb +97 -95
- data/lib/rdoc/code_object/normal_class.rb +77 -78
- data/lib/rdoc/code_object/normal_module.rb +61 -59
- data/lib/rdoc/code_object/require.rb +23 -39
- data/lib/rdoc/code_object/single_class.rb +21 -19
- data/lib/rdoc/code_object/top_level.rb +212 -219
- data/lib/rdoc/code_object.rb +305 -303
- data/lib/rdoc/comment.rb +275 -273
- data/lib/rdoc/cross_reference.rb +192 -190
- data/lib/rdoc/encoding.rb +105 -103
- data/lib/rdoc/erb_partial.rb +13 -11
- data/lib/rdoc/erbio.rb +29 -27
- data/lib/rdoc/generator/aliki.rb +161 -153
- data/lib/rdoc/generator/darkfish.rb +645 -635
- data/lib/rdoc/generator/json_index.rb +233 -229
- data/lib/rdoc/generator/markup.rb +164 -146
- data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
- data/lib/rdoc/generator/pot/po.rb +52 -51
- data/lib/rdoc/generator/pot/po_entry.rb +138 -132
- data/lib/rdoc/generator/pot.rb +85 -81
- data/lib/rdoc/generator/ri.rb +23 -19
- data/lib/rdoc/generator/template/aliki/DESIGN.md +6 -4
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
- data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
- data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
- data/lib/rdoc/generator.rb +48 -46
- data/lib/rdoc/i18n/locale.rb +99 -95
- data/lib/rdoc/i18n/text.rb +109 -105
- data/lib/rdoc/i18n.rb +7 -5
- data/lib/rdoc/markdown/byte_runtime.rb +80 -0
- data/lib/rdoc/markdown.kpeg +15 -11
- data/lib/rdoc/markdown.rb +40 -47
- data/lib/rdoc/markup/block_quote.rb +12 -8
- data/lib/rdoc/markup/document.rb +127 -123
- data/lib/rdoc/markup/formatter.rb +219 -215
- data/lib/rdoc/markup/include.rb +33 -29
- data/lib/rdoc/markup/indented_paragraph.rb +37 -33
- data/lib/rdoc/markup/inline_parser.rb +281 -277
- data/lib/rdoc/markup/list.rb +80 -88
- data/lib/rdoc/markup/list_item.rb +73 -85
- data/lib/rdoc/markup/paragraph.rb +23 -19
- data/lib/rdoc/markup/parser.rb +501 -497
- data/lib/rdoc/markup/pre_process.rb +283 -279
- data/lib/rdoc/markup/raw.rb +2 -2
- data/lib/rdoc/markup/rule.rb +16 -12
- data/lib/rdoc/markup/to_ansi.rb +143 -139
- data/lib/rdoc/markup/to_bs.rb +72 -68
- data/lib/rdoc/markup/to_html.rb +594 -565
- data/lib/rdoc/markup/to_html_crossref.rb +234 -230
- data/lib/rdoc/markup/to_html_snippet.rb +232 -227
- data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
- data/lib/rdoc/markup/to_label.rb +63 -59
- data/lib/rdoc/markup/to_markdown.rb +212 -208
- data/lib/rdoc/markup/to_rdoc.rb +336 -332
- data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
- data/lib/rdoc/markup/to_test.rb +60 -56
- data/lib/rdoc/markup/to_tt_only.rb +84 -80
- data/lib/rdoc/markup/verbatim.rb +62 -58
- data/lib/rdoc/markup.rb +198 -196
- data/lib/rdoc/options.rb +1063 -1061
- data/lib/rdoc/parser/c.rb +1039 -1037
- data/lib/rdoc/parser/changelog.rb +319 -315
- data/lib/rdoc/parser/markdown.rb +17 -13
- data/lib/rdoc/parser/rbs.rb +239 -235
- data/lib/rdoc/parser/rd.rb +17 -13
- data/lib/rdoc/parser/ruby.rb +1245 -1124
- data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
- data/lib/rdoc/parser/simple.rb +31 -27
- data/lib/rdoc/parser/text.rb +12 -8
- data/lib/rdoc/parser.rb +228 -220
- data/lib/rdoc/rbs_helper.rb +1 -1
- data/lib/rdoc/rd/inline.rb +57 -53
- data/lib/rdoc/rd.rb +90 -88
- data/lib/rdoc/rdoc.rb +500 -491
- data/lib/rdoc/ri/driver.rb +1140 -1135
- data/lib/rdoc/ri/formatter.rb +7 -3
- data/lib/rdoc/ri/paths.rb +140 -136
- data/lib/rdoc/ri/servlet.rb +354 -350
- data/lib/rdoc/ri/store.rb +4 -2
- data/lib/rdoc/ri/task.rb +55 -51
- data/lib/rdoc/ri.rb +14 -12
- data/lib/rdoc/rubygems_hook.rb +183 -181
- data/lib/rdoc/server.rb +349 -347
- data/lib/rdoc/stats/normal.rb +46 -42
- data/lib/rdoc/stats/quiet.rb +39 -35
- data/lib/rdoc/stats/verbose.rb +35 -31
- data/lib/rdoc/stats.rb +365 -363
- data/lib/rdoc/store.rb +888 -902
- data/lib/rdoc/task.rb +260 -256
- data/lib/rdoc/text.rb +135 -133
- data/lib/rdoc/token_stream.rb +101 -93
- data/lib/rdoc/tom_doc.rb +203 -201
- data/lib/rdoc/version.rb +1 -1
- metadata +4 -5
- data/lib/rdoc/markdown/literals.kpeg +0 -21
- data/lib/rdoc/markdown/literals.rb +0 -454
data/lib/rdoc/ri/servlet.rb
CHANGED
|
@@ -10,202 +10,204 @@ rescue LoadError
|
|
|
10
10
|
abort "webrick is not found. You may need to `gem install webrick` to install webrick."
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
# server.
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
13
|
+
module RDoc
|
|
14
|
+
module RI
|
|
15
|
+
##
|
|
16
|
+
# This is a WEBrick servlet that allows you to browse ri documentation.
|
|
17
|
+
#
|
|
18
|
+
# You can show documentation through either `ri --server` or, with RubyGems
|
|
19
|
+
# 2.0 or newer, `gem server`. For ri, the server runs on port 8214 by
|
|
20
|
+
# default. For RubyGems the server runs on port 8808 by default.
|
|
21
|
+
#
|
|
22
|
+
# You can use this servlet in your own project by mounting it on a WEBrick
|
|
23
|
+
# server:
|
|
24
|
+
#
|
|
25
|
+
# require 'webrick'
|
|
26
|
+
#
|
|
27
|
+
# server = WEBrick::HTTPServer.new Port: 8000
|
|
28
|
+
#
|
|
29
|
+
# server.mount '/', RDoc::RI::Servlet
|
|
30
|
+
#
|
|
31
|
+
# If you want to mount the servlet some other place than the root, provide the
|
|
32
|
+
# base path when mounting:
|
|
33
|
+
#
|
|
34
|
+
# server.mount '/rdoc', RDoc::RI::Servlet, '/rdoc'
|
|
35
|
+
|
|
36
|
+
class Servlet < WEBrick::HTTPServlet::AbstractServlet
|
|
37
|
+
|
|
38
|
+
@server_stores = Hash.new { |hash, server| hash[server] = {} }
|
|
39
|
+
@cache = Hash.new { |hash, store| hash[store] = {} }
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Maps an asset type to its path on the filesystem
|
|
43
|
+
|
|
44
|
+
attr_reader :asset_dirs
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# An RDoc::Options instance used for rendering options
|
|
48
|
+
|
|
49
|
+
attr_reader :options
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Creates an instance of this servlet that shares cached data between
|
|
53
|
+
# requests.
|
|
54
|
+
|
|
55
|
+
def self.get_instance(server, *options) # :nodoc:
|
|
56
|
+
stores = @server_stores[server]
|
|
57
|
+
|
|
58
|
+
new server, stores, @cache, *options
|
|
59
|
+
end
|
|
89
60
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
61
|
+
##
|
|
62
|
+
# Creates a new WEBrick servlet.
|
|
63
|
+
#
|
|
64
|
+
# Use +mount_path+ when mounting the servlet somewhere other than /.
|
|
65
|
+
#
|
|
66
|
+
# Use +extra_doc_dirs+ for additional documentation directories.
|
|
67
|
+
#
|
|
68
|
+
# +server+ is provided automatically by WEBrick when mounting. +stores+ and
|
|
69
|
+
# +cache+ are provided automatically by the servlet.
|
|
70
|
+
|
|
71
|
+
def initialize(server, stores, cache, mount_path = nil, extra_doc_dirs = [])
|
|
72
|
+
super server
|
|
73
|
+
|
|
74
|
+
@cache = cache
|
|
75
|
+
@mount_path = mount_path
|
|
76
|
+
@extra_doc_dirs = extra_doc_dirs
|
|
77
|
+
@stores = stores
|
|
78
|
+
|
|
79
|
+
@options = Options.new
|
|
80
|
+
@options.op_dir = '.'
|
|
81
|
+
|
|
82
|
+
darkfish_dir = nil
|
|
83
|
+
|
|
84
|
+
# HACK dup
|
|
85
|
+
$LOAD_PATH.each do |path|
|
|
86
|
+
darkfish_dir = File.join path, 'rdoc/generator/template/darkfish/'
|
|
87
|
+
next unless File.directory? darkfish_dir
|
|
88
|
+
@options.template_dir = darkfish_dir
|
|
89
|
+
break
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
@asset_dirs = {
|
|
93
|
+
:darkfish => darkfish_dir,
|
|
94
|
+
:json_index =>
|
|
95
|
+
File.expand_path('../generator/template/json_index/', __FILE__),
|
|
96
|
+
}
|
|
97
|
+
end
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
##
|
|
100
|
+
# Serves the asset at the path in +req+ for +generator_name+ via +res+.
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
def asset(generator_name, req, res)
|
|
103
|
+
asset_dir = @asset_dirs[generator_name]
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
asset_path = File.join asset_dir, req.path
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
if_modified_since req, res, asset_path
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
res.body = File.read asset_path
|
|
108
110
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
res.content_type = case req.path
|
|
112
|
+
when /\.css\z/ then 'text/css'
|
|
113
|
+
when /\.js\z/ then 'application/javascript'
|
|
114
|
+
else 'application/octet-stream'
|
|
115
|
+
end
|
|
116
|
+
end
|
|
115
117
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
118
|
+
##
|
|
119
|
+
# GET request entry point. Fills in +res+ for the path, etc. in +req+.
|
|
120
|
+
|
|
121
|
+
def do_GET(req, res)
|
|
122
|
+
req.path.sub!(/\A#{Regexp.escape @mount_path}/, '') if @mount_path
|
|
123
|
+
|
|
124
|
+
case req.path
|
|
125
|
+
when '/'
|
|
126
|
+
root req, res
|
|
127
|
+
when '/js/darkfish.js', '/js/jquery.js', '/js/search.js',
|
|
128
|
+
%r%^/css/%, %r%^/images/%, %r%^/fonts/%
|
|
129
|
+
asset :darkfish, req, res
|
|
130
|
+
when '/js/navigation.js', '/js/searcher.js'
|
|
131
|
+
asset :json_index, req, res
|
|
132
|
+
when '/js/search_index.js'
|
|
133
|
+
root_search req, res
|
|
134
|
+
else
|
|
135
|
+
show_documentation req, res
|
|
136
|
+
end
|
|
137
|
+
rescue WEBrick::HTTPStatus::NotFound => e
|
|
138
|
+
generator = generator_for ::RDoc::Store.new(@options)
|
|
139
|
+
|
|
140
|
+
not_found generator, req, res, e.message
|
|
141
|
+
rescue WEBrick::HTTPStatus::Status
|
|
142
|
+
raise
|
|
143
|
+
rescue => e
|
|
144
|
+
error e, req, res
|
|
145
|
+
end
|
|
144
146
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
147
|
+
##
|
|
148
|
+
# Fills in +res+ with the class, module or page for +req+ from +store+.
|
|
149
|
+
#
|
|
150
|
+
# +path+ is relative to the mount_path and is used to determine the class,
|
|
151
|
+
# module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
|
|
152
|
+
# +generator+ is used to create the page.
|
|
153
|
+
|
|
154
|
+
def documentation_page(store, generator, path, req, res)
|
|
155
|
+
text_name = path.chomp '.html'
|
|
156
|
+
name = text_name.gsub '/', '::'
|
|
157
|
+
|
|
158
|
+
if klass = store.find_class_or_module(name)
|
|
159
|
+
res.body = generator.generate_class klass
|
|
160
|
+
elsif page = store.find_text_page(name.sub(/_([^_]*)\z/, '.\1'))
|
|
161
|
+
res.body = generator.generate_page page
|
|
162
|
+
elsif page = store.find_text_page(text_name.sub(/_([^_]*)\z/, '.\1'))
|
|
163
|
+
res.body = generator.generate_page page
|
|
164
|
+
else
|
|
165
|
+
not_found generator, req, res
|
|
166
|
+
end
|
|
167
|
+
end
|
|
166
168
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
##
|
|
170
|
+
# Creates the JSON search index on +res+ for the given +store+. +generator+
|
|
171
|
+
# must respond to \#json_index to build. +req+ is ignored.
|
|
170
172
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
def documentation_search(store, generator, req, res)
|
|
174
|
+
json_index = @cache[store].fetch :json_index do
|
|
175
|
+
@cache[store][:json_index] =
|
|
176
|
+
JSON.dump generator.json_index.build_index
|
|
177
|
+
end
|
|
176
178
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
179
|
+
res.content_type = 'application/javascript'
|
|
180
|
+
res.body = "var search_data = #{json_index}"
|
|
181
|
+
end
|
|
180
182
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
##
|
|
184
|
+
# Returns the RDoc::Store and path relative to +mount_path+ for
|
|
185
|
+
# documentation at +path+.
|
|
184
186
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
+
def documentation_source(path)
|
|
188
|
+
_, source_name, path = path.split '/', 3
|
|
187
189
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
store = @stores[source_name]
|
|
191
|
+
return store, path if store
|
|
190
192
|
|
|
191
|
-
|
|
193
|
+
store = store_for source_name
|
|
192
194
|
|
|
193
|
-
|
|
195
|
+
store.load_all
|
|
194
196
|
|
|
195
|
-
|
|
197
|
+
@stores[source_name] = store
|
|
196
198
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
return store, path
|
|
200
|
+
end
|
|
199
201
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
##
|
|
203
|
+
# Generates an error page for the +exception+ while handling +req+ on +res+.
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
+
def error(exception, req, res)
|
|
206
|
+
backtrace = exception.backtrace.join "\n"
|
|
205
207
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
208
|
+
res.content_type = 'text/html'
|
|
209
|
+
res.status = 500
|
|
210
|
+
res.body = <<-BODY
|
|
209
211
|
<!DOCTYPE html>
|
|
210
212
|
<html>
|
|
211
213
|
<head>
|
|
@@ -219,7 +221,7 @@ class RDoc::RI::Servlet < WEBrick::HTTPServlet::AbstractServlet
|
|
|
219
221
|
<h1>Error</h1>
|
|
220
222
|
|
|
221
223
|
<p>While processing <code>#{ERB::Util.html_escape req.request_uri}</code> the
|
|
222
|
-
RDoc (#{ERB::Util.html_escape
|
|
224
|
+
RDoc (#{ERB::Util.html_escape(VERSION)}) server has encountered a
|
|
223
225
|
<code>#{ERB::Util.html_escape exception.class}</code>
|
|
224
226
|
exception:
|
|
225
227
|
|
|
@@ -238,215 +240,217 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
|
|
|
238
240
|
</body>
|
|
239
241
|
</html>
|
|
240
242
|
BODY
|
|
241
|
-
|
|
243
|
+
end
|
|
242
244
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
##
|
|
246
|
+
# Instantiates a Darkfish generator for +store+
|
|
245
247
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
def generator_for(store)
|
|
249
|
+
generator = Generator::Darkfish.new store, @options
|
|
250
|
+
generator.file_output = false
|
|
251
|
+
generator.asset_rel_path = '..'
|
|
252
|
+
generator.setup
|
|
251
253
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
rdoc = RDoc.new
|
|
255
|
+
rdoc.store = store
|
|
256
|
+
rdoc.generator = generator
|
|
257
|
+
rdoc.options = @options
|
|
256
258
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
+
@options.main_page = store.main
|
|
260
|
+
@options.title = store.title
|
|
259
261
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
+
generator
|
|
263
|
+
end
|
|
262
264
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
##
|
|
266
|
+
# Handles the If-Modified-Since HTTP header on +req+ for +path+. If the
|
|
267
|
+
# file has not been modified a Not Modified response is returned. If the
|
|
268
|
+
# file has been modified a Last-Modified header is added to +res+.
|
|
267
269
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
def if_modified_since(req, res, path = nil)
|
|
271
|
+
last_modified = File.stat(path).mtime if path
|
|
270
272
|
|
|
271
|
-
|
|
273
|
+
res['last-modified'] = last_modified.httpdate
|
|
272
274
|
|
|
273
|
-
|
|
275
|
+
return unless ims = req['if-modified-since']
|
|
274
276
|
|
|
275
|
-
|
|
277
|
+
ims = Time.parse ims
|
|
276
278
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
unless ims < last_modified
|
|
280
|
+
res.body = ''
|
|
281
|
+
raise WEBrick::HTTPStatus::NotModified
|
|
282
|
+
end
|
|
283
|
+
end
|
|
282
284
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
285
|
+
##
|
|
286
|
+
# Returns an Array of installed documentation.
|
|
287
|
+
#
|
|
288
|
+
# Each entry contains the documentation name (gem name, 'Ruby
|
|
289
|
+
# Documentation', etc.), the path relative to the mount point, whether the
|
|
290
|
+
# documentation exists, the type of documentation (See RDoc::RI::Paths#each)
|
|
291
|
+
# and the filesystem to the RDoc::Store for the documentation.
|
|
292
|
+
|
|
293
|
+
def installed_docs
|
|
294
|
+
extra_counter = 0
|
|
295
|
+
ri_paths.map do |path, type|
|
|
296
|
+
store = ::RDoc::Store.new(@options, path: path, type: type)
|
|
297
|
+
exists = File.exist? store.cache_path
|
|
298
|
+
|
|
299
|
+
case type
|
|
300
|
+
when :gem
|
|
301
|
+
gem_path = path[%r%/([^/]*)/ri$%, 1]
|
|
302
|
+
[gem_path, "#{gem_path}/", exists, type, path]
|
|
303
|
+
when :system
|
|
304
|
+
['Ruby Documentation', 'ruby/', exists, type, path]
|
|
305
|
+
when :site
|
|
306
|
+
['Site Documentation', 'site/', exists, type, path]
|
|
307
|
+
when :home
|
|
308
|
+
['Home Documentation', 'home/', exists, type, path]
|
|
309
|
+
when :extra
|
|
310
|
+
extra_counter += 1
|
|
311
|
+
store.load_cache if exists
|
|
312
|
+
title = store.title || "Extra Documentation"
|
|
313
|
+
[title, "extra-#{extra_counter}/", exists, type, path]
|
|
314
|
+
end
|
|
315
|
+
end
|
|
312
316
|
end
|
|
313
|
-
end
|
|
314
|
-
end
|
|
315
317
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
+
##
|
|
319
|
+
# Returns a 404 page built by +generator+ for +req+ on +res+.
|
|
318
320
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
321
|
+
def not_found(generator, req, res, message = nil)
|
|
322
|
+
message ||= "The page <kbd>#{ERB::Util.h req.path}</kbd> was not found"
|
|
323
|
+
res.body = generator.generate_servlet_not_found message
|
|
324
|
+
res.status = 404
|
|
325
|
+
end
|
|
324
326
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
+
##
|
|
328
|
+
# Enumerates the ri paths. See RDoc::RI::Paths#each
|
|
327
329
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
def ri_paths(&block)
|
|
331
|
+
RI::Paths.each true, true, true, :all, *@extra_doc_dirs, &block #TODO: pass extra_dirs
|
|
332
|
+
end
|
|
331
333
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
+
##
|
|
335
|
+
# Generates the root page on +res+. +req+ is ignored.
|
|
334
336
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
+
def root(req, res)
|
|
338
|
+
generator = Generator::Darkfish.new nil, @options
|
|
337
339
|
|
|
338
|
-
|
|
340
|
+
res.body = generator.generate_servlet_root installed_docs
|
|
339
341
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
+
res.content_type = 'text/html'
|
|
343
|
+
end
|
|
342
344
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
345
|
+
##
|
|
346
|
+
# Generates a search index for the root page on +res+. +req+ is ignored.
|
|
347
|
+
|
|
348
|
+
def root_search(req, res)
|
|
349
|
+
search_index = []
|
|
350
|
+
info = []
|
|
351
|
+
|
|
352
|
+
installed_docs.map do |name, href, exists, type, path|
|
|
353
|
+
next unless exists
|
|
354
|
+
|
|
355
|
+
search_index << name
|
|
356
|
+
|
|
357
|
+
case type
|
|
358
|
+
when :gem
|
|
359
|
+
gemspec = path.gsub(%r%/doc/([^/]*?)/ri$%,
|
|
360
|
+
'/specifications/\1.gemspec')
|
|
361
|
+
|
|
362
|
+
spec = Gem::Specification.load gemspec
|
|
363
|
+
|
|
364
|
+
path = spec.full_name
|
|
365
|
+
comment = spec.summary
|
|
366
|
+
when :system
|
|
367
|
+
path = 'ruby'
|
|
368
|
+
comment = 'Documentation for the Ruby standard library'
|
|
369
|
+
when :site
|
|
370
|
+
path = 'site'
|
|
371
|
+
comment = 'Documentation for non-gem libraries'
|
|
372
|
+
when :home
|
|
373
|
+
path = 'home'
|
|
374
|
+
comment = 'Documentation from your home directory'
|
|
375
|
+
when :extra
|
|
376
|
+
comment = name
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
info << [name, '', path, '', comment]
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
index = {
|
|
383
|
+
:index => {
|
|
384
|
+
:searchIndex => search_index,
|
|
385
|
+
:longSearchIndex => search_index,
|
|
386
|
+
:info => info,
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
res.body = "var search_data = #{JSON.dump index};"
|
|
391
|
+
res.content_type = 'application/javascript'
|
|
375
392
|
end
|
|
376
393
|
|
|
377
|
-
|
|
378
|
-
|
|
394
|
+
##
|
|
395
|
+
# Displays documentation for +req+ on +res+, whether that be HTML or some
|
|
396
|
+
# asset.
|
|
397
|
+
|
|
398
|
+
def show_documentation(req, res)
|
|
399
|
+
store, path = documentation_source req.path
|
|
400
|
+
|
|
401
|
+
if_modified_since req, res, store.cache_path
|
|
402
|
+
|
|
403
|
+
generator = generator_for store
|
|
404
|
+
|
|
405
|
+
case path
|
|
406
|
+
when nil, '', 'index.html'
|
|
407
|
+
res.body = generator.generate_index
|
|
408
|
+
when 'table_of_contents.html'
|
|
409
|
+
res.body = generator.generate_table_of_contents
|
|
410
|
+
when 'js/search_index.js'
|
|
411
|
+
documentation_search store, generator, req, res
|
|
412
|
+
else
|
|
413
|
+
documentation_page store, generator, path, req, res
|
|
414
|
+
end
|
|
415
|
+
ensure
|
|
416
|
+
res.content_type ||= 'text/html'
|
|
417
|
+
end
|
|
379
418
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
:searchIndex => search_index,
|
|
383
|
-
:longSearchIndex => search_index,
|
|
384
|
-
:info => info,
|
|
385
|
-
}
|
|
386
|
-
}
|
|
419
|
+
##
|
|
420
|
+
# Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
|
|
387
421
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
422
|
+
def store_for(source_name)
|
|
423
|
+
case source_name
|
|
424
|
+
when 'home'
|
|
425
|
+
::RDoc::Store.new(@options, path: RI::Paths.home_dir, type: :home)
|
|
426
|
+
when 'ruby'
|
|
427
|
+
::RDoc::Store.new(@options, path: RI::Paths.system_dir, type: :system)
|
|
428
|
+
when 'site'
|
|
429
|
+
::RDoc::Store.new(@options, path: RI::Paths.site_dir, type: :site)
|
|
430
|
+
when /\Aextra-(\d+)\z/
|
|
431
|
+
index = $1.to_i - 1
|
|
432
|
+
ri_dir = installed_docs[index][4]
|
|
433
|
+
::RDoc::Store.new(@options, path: ri_dir, type: :extra)
|
|
434
|
+
else
|
|
435
|
+
ri_dir, type = ri_paths.find do |dir, dir_type|
|
|
436
|
+
next unless dir_type == :gem
|
|
391
437
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
# asset.
|
|
438
|
+
source_name == dir[%r%/([^/]*)/ri$%, 1]
|
|
439
|
+
end
|
|
395
440
|
|
|
396
|
-
|
|
397
|
-
|
|
441
|
+
raise WEBrick::HTTPStatus::NotFound,
|
|
442
|
+
"Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir
|
|
398
443
|
|
|
399
|
-
|
|
444
|
+
store = ::RDoc::Store.new(@options, path: ri_dir, type: type)
|
|
400
445
|
|
|
401
|
-
|
|
446
|
+
return store if File.exist? store.cache_path
|
|
402
447
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
res.body = generator.generate_index
|
|
406
|
-
when 'table_of_contents.html' then
|
|
407
|
-
res.body = generator.generate_table_of_contents
|
|
408
|
-
when 'js/search_index.js' then
|
|
409
|
-
documentation_search store, generator, req, res
|
|
410
|
-
else
|
|
411
|
-
documentation_page store, generator, path, req, res
|
|
412
|
-
end
|
|
413
|
-
ensure
|
|
414
|
-
res.content_type ||= 'text/html'
|
|
415
|
-
end
|
|
448
|
+
raise WEBrick::HTTPStatus::NotFound,
|
|
449
|
+
"Could not find documentation for \"#{ERB::Util.html_escape(source_name)}\". Please run `gem rdoc --ri gem_name`"
|
|
416
450
|
|
|
417
|
-
|
|
418
|
-
# Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
|
|
419
|
-
|
|
420
|
-
def store_for(source_name)
|
|
421
|
-
case source_name
|
|
422
|
-
when 'home' then
|
|
423
|
-
RDoc::Store.new(@options, path: RDoc::RI::Paths.home_dir, type: :home)
|
|
424
|
-
when 'ruby' then
|
|
425
|
-
RDoc::Store.new(@options, path: RDoc::RI::Paths.system_dir, type: :system)
|
|
426
|
-
when 'site' then
|
|
427
|
-
RDoc::Store.new(@options, path: RDoc::RI::Paths.site_dir, type: :site)
|
|
428
|
-
when /\Aextra-(\d+)\z/ then
|
|
429
|
-
index = $1.to_i - 1
|
|
430
|
-
ri_dir = installed_docs[index][4]
|
|
431
|
-
RDoc::Store.new(@options, path: ri_dir, type: :extra)
|
|
432
|
-
else
|
|
433
|
-
ri_dir, type = ri_paths.find do |dir, dir_type|
|
|
434
|
-
next unless dir_type == :gem
|
|
435
|
-
|
|
436
|
-
source_name == dir[%r%/([^/]*)/ri$%, 1]
|
|
451
|
+
end
|
|
437
452
|
end
|
|
438
453
|
|
|
439
|
-
raise WEBrick::HTTPStatus::NotFound,
|
|
440
|
-
"Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir
|
|
441
|
-
|
|
442
|
-
store = RDoc::Store.new(@options, path: ri_dir, type: type)
|
|
443
|
-
|
|
444
|
-
return store if File.exist? store.cache_path
|
|
445
|
-
|
|
446
|
-
raise WEBrick::HTTPStatus::NotFound,
|
|
447
|
-
"Could not find documentation for \"#{ERB::Util.html_escape(source_name)}\". Please run `gem rdoc --ri gem_name`"
|
|
448
|
-
|
|
449
454
|
end
|
|
450
455
|
end
|
|
451
|
-
|
|
452
456
|
end
|