summaryrefslogtreecommitdiff
path: root/lib/rdoc
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-07 05:22:50 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-07 05:22:50 +0000
commit85e3560a3bfb1652128d3336400f852b863f6c07 (patch)
tree0310bf56d334b36c224603b6bfe930f7385f0faf /lib/rdoc
parent08f0db2c68a9e306f3a637e9d32d9e7b8b1f2e92 (diff)
* lib/rdoc/markup/to_joined_paragraph.rb: Completed documentation
* lib/rdoc/parser/c.rb: ditto * lib/rdoc/parser/changelog.rb: ditto * lib/rdoc/servlet.rb: ditto * lib/rdoc/store.rb: ditto * lib/rdoc/store.rb: Improved HTML error page. Completed documentation * lib/rdoc/parser/ruby.rb: Fixed bug attaching a comment to A::B = 42 * test/rdoc/test_rdoc_parser_ruby.rb: Test for above * test/rdoc/test_rdoc_comment.rb: Removed garbage git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38256 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc')
-rw-r--r--lib/rdoc/markup/to_joined_paragraph.rb7
-rw-r--r--lib/rdoc/parser/c.rb4
-rw-r--r--lib/rdoc/parser/changelog.rb51
-rw-r--r--lib/rdoc/parser/ruby.rb54
-rw-r--r--lib/rdoc/servlet.rb117
-rw-r--r--lib/rdoc/store.rb2
6 files changed, 219 insertions, 16 deletions
diff --git a/lib/rdoc/markup/to_joined_paragraph.rb b/lib/rdoc/markup/to_joined_paragraph.rb
index d91eb439f0..6982d86697 100644
--- a/lib/rdoc/markup/to_joined_paragraph.rb
+++ b/lib/rdoc/markup/to_joined_paragraph.rb
@@ -12,12 +12,15 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
super nil
end
- def start_accepting
+ def start_accepting # :nodoc:
end
- def end_accepting
+ def end_accepting # :nodoc:
end
+ ##
+ # Converts the parts of +paragraph+ to a single entry.
+
def accept_paragraph paragraph
parts = []
string = false
diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb
index 31be27169c..d371ed0e6a 100644
--- a/lib/rdoc/parser/c.rb
+++ b/lib/rdoc/parser/c.rb
@@ -446,6 +446,10 @@ class RDoc::Parser::C < RDoc::Parser
end
end
+ ##
+ # Creates classes and module that were missing were defined due to the file
+ # order being different than the declaration order.
+
def do_missing
return if @missing_dependencies.empty?
diff --git a/lib/rdoc/parser/changelog.rb b/lib/rdoc/parser/changelog.rb
index 6a21506a93..fd7114daee 100644
--- a/lib/rdoc/parser/changelog.rb
+++ b/lib/rdoc/parser/changelog.rb
@@ -1,11 +1,28 @@
require 'time'
+##
+# A ChangeLog file parser.
+#
+# This parser converts a ChangeLog into an RDoc::Markup::Document. When
+# viewed as HTML a ChangeLog page will have an entry for each day's entries in
+# the sidebar table of contents.
+#
+# This parser is meant to parse the MRI ChangeLog, but can be used to parse any
+# {GNU style Change
+# Log}[http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html].
+
class RDoc::Parser::ChangeLog < RDoc::Parser
include RDoc::Parser::Text
parse_files_matching(/(\/|\\|\A)ChangeLog[^\/\\]*\z/)
+ ##
+ # Attaches the +continuation+ of the previous line to the +entry_body+.
+ #
+ # Continued function listings are joined together as a single entry.
+ # Continued descriptions are joined to make a single paragraph.
+
def continue_entry_body entry_body, continuation
return unless last = entry_body.last
@@ -21,6 +38,9 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
end
end
+ ##
+ # Creates an RDoc::Markup::Document given the +groups+ of ChangeLog entries.
+
def create_document groups
doc = RDoc::Markup::Document.new
doc.omit_headings_below = 2
@@ -39,6 +59,10 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
doc
end
+ ##
+ # Returns a list of ChangeLog entries an RDoc::Markup nodes for the given
+ # +entries+.
+
def create_entries entries
out = []
@@ -52,6 +76,10 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
out
end
+ ##
+ # Returns an RDoc::Markup::List containing the given +items+ in the
+ # ChangeLog
+
def create_items items
list = RDoc::Markup::List.new :NOTE
@@ -69,12 +97,30 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
list
end
+ ##
+ # Groups +entries+ by date.
+
def group_entries entries
- entries.group_by do |title, body|
+ entries.group_by do |title, _|
Time.parse(title).strftime "%Y-%m-%d"
end
end
+ ##
+ # Parses the entries in the ChangeLog.
+ #
+ # Returns an Array of each ChangeLog entry in order of parsing.
+ #
+ # A ChangeLog entry is an Array containing the ChangeLog title (date and
+ # committer) and an Array of ChangeLog items (file and function changed with
+ # description).
+ #
+ # An example result would be:
+ #
+ # [ 'Tue Dec 4 08:33:46 2012 Eric Hodel <drbrain@segment7.net>',
+ # [ 'README.EXT: Converted to RDoc format',
+ # 'README.EXT.ja: ditto']]
+
def parse_entries
entries = []
entry_name = nil
@@ -122,6 +168,9 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
entries
end
+ ##
+ # Converts the ChangeLog into an RDoc::Markup::Document
+
def scan
entries = parse_entries
grouped_entries = group_entries entries
diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb
index fe461ff389..31e31b5ce9 100644
--- a/lib/rdoc/parser/ruby.rb
+++ b/lib/rdoc/parser/ruby.rb
@@ -240,7 +240,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# with :: separated named) and return the ultimate name, the associated
# container, and the given name (with the ::).
- def get_class_or_module container
+ def get_class_or_module container, ignore_constants = false
skip_tkspace
name_t = get_tk
given_name = ''
@@ -259,9 +259,16 @@ class RDoc::Parser::Ruby < RDoc::Parser
while TkCOLON2 === peek_tk do
prev_container = container
container = container.find_module_named name_t.name
- container ||= prev_container.add_module RDoc::NormalModule, name_t.name
+ container ||=
+ if ignore_constants then
+ RDoc::Context.new
+ else
+ c = prev_container.add_module RDoc::NormalModule, name_t.name
+ c.ignore unless prev_container.document_children
+ c
+ end
- container.ignore unless prev_container.document_children
+ container.record_location @top_level
get_tk
skip_tkspace false
@@ -663,9 +670,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
##
- # Parses a constant in +context+ with +comment+
+ # Parses a constant in +context+ with +comment+. If +ignore_constants+ is
+ # true, no found constants will be added to RDoc.
- def parse_constant container, tk, comment
+ def parse_constant container, tk, comment, ignore_constants = false
offset = tk.seek
line_no = tk.line_no
@@ -676,6 +684,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
eq_tk = get_tk
+ if TkCOLON2 === eq_tk then
+ unget_tk eq_tk
+ unget_tk tk
+
+ container, name_t, = get_class_or_module container, ignore_constants
+
+ name = name_t.name
+
+ eq_tk = get_tk
+ end
+
unless TkASSIGN === eq_tk then
unget_tk eq_tk
return false
@@ -1335,6 +1354,26 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
##
+ # Parses a rescue
+
+ def parse_rescue
+ skip_tkspace false
+
+ while tk = get_tk
+ case tk
+ when TkNL, TkSEMICOLON then
+ break
+ when TkCOMMA then
+ skip_tkspace false
+
+ get_tk if TkNL === peek_tk
+ end
+
+ skip_tkspace false
+ end
+ end
+
+ ##
# The core of the ruby parser.
def parse_statements(container, single = NORMAL, current_method = nil,
@@ -1407,7 +1446,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
parse_method container, single, tk, comment
when TkCONSTANT then
- unless parse_constant container, tk, comment then
+ unless parse_constant container, tk, comment, current_method then
try_parse_comment = true
end
@@ -1441,6 +1480,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
when TkSUPER then
current_method.calls_super = true if current_method
+ when TkRESCUE then
+ parse_rescue
+
when TkIDENTIFIER then
if nest == 1 and current_method.nil? then
case tk.name
diff --git a/lib/rdoc/servlet.rb b/lib/rdoc/servlet.rb
index 3df366b967..71b2911fc0 100644
--- a/lib/rdoc/servlet.rb
+++ b/lib/rdoc/servlet.rb
@@ -2,21 +2,60 @@ require 'rdoc'
require 'time'
require 'webrick'
+##
+# This is a WEBrick servlet that allows you to browse ri documentation.
+#
+# You can show documentation through either `ri --server` or, with RubyGems
+# 2.0 or newer, `gem server`. For ri, the server runs on port 8214 by
+# default. For RubyGems the server runs on port 8808 by default.
+#
+# You can use this servlet in your own project by mounting it on a WEBrick
+# server:
+#
+# require 'webrick'
+#
+# server = WEBrick::HTTPServer.new Port: 8000
+#
+# server.mount '/', RDoc::Servlet
+#
+# If you want to mount the servlet some other place than the root, provide the
+# base path when mounting:
+#
+# server.mount '/rdoc', RDoc::Servlet, '/rdoc'
+
class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
@server_stores = Hash.new { |hash, server| hash[server] = {} }
@cache = Hash.new { |hash, store| hash[store] = {} }
+ ##
+ # Maps an asset type to its path on the filesystem
+
attr_reader :asset_dirs
+ ##
+ # An RDoc::Options instance used for rendering options
+
attr_reader :options
- def self.get_instance server, *options
+ ##
+ # Creates an instance of this servlet that shares cached data between
+ # requests.
+
+ def self.get_instance server, *options # :nodoc:
stores = @server_stores[server]
new server, stores, @cache, *options
end
+ ##
+ # Creates a new WEBrick servlet.
+ #
+ # Use +mount_path+ when mounting the servlet somewhere other than /.
+ #
+ # +server+ is provided automatically by WEBrick when mounting. +stores+ and
+ # +cache+ are provided automatically by the servlet.
+
def initialize server, stores, cache, mount_path = nil
super server
@@ -44,6 +83,9 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
}
end
+ ##
+ # Serves the asset at the path in +req+ for +generator_name+ via +res+.
+
def asset generator_name, req, res
asset_dir = @asset_dirs[generator_name]
@@ -60,6 +102,9 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
end
end
+ ##
+ # GET request entry point. Fills in +res+ for the path, etc. in +req+.
+
def do_GET req, res
req.path.sub!(/^#{Regexp.escape @mount_path}/o, '') if @mount_path
@@ -82,6 +127,13 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
error e, req, res
end
+ ##
+ # Fills in +res+ with the class, module or page for +req+ from +store+.
+ #
+ # +path+ is relative to the mount_path and is used to determine the class,
+ # module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
+ # +generator+ is used to create the page.
+
def documentation_page store, generator, path, req, res
name = path.sub(/.html$/, '').gsub '/', '::'
@@ -94,6 +146,10 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
end
end
+ ##
+ # Creates the JSON search index on +res+ for the given +store+. +generator+
+ # must respond to \#json_index to build. +req+ is ignored.
+
def documentation_search store, generator, req, res
json_index = @cache[store].fetch :json_index do
@cache[store][:json_index] =
@@ -104,6 +160,10 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
res.body = "var search_data = #{json_index}"
end
+ ##
+ # Returns the RDoc::Store and path relative to +mount_path+ for
+ # documentation at +path+.
+
def documentation_source path
_, source_name, path = path.split '/', 3
@@ -119,8 +179,11 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
return store, path
end
- def error e, req, res
- backtrace = e.backtrace.join "\n"
+ ##
+ # Generates an error page for the +exception+ while handling +req+ on +res+.
+
+ def error exception, req, res
+ backtrace = exception.backtrace.join "\n"
res.content_type = 'text/html'
res.status = 500
@@ -130,7 +193,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
-<title>Error - #{ERB::Util.html_escape e.class}</title>
+<title>Error - #{ERB::Util.html_escape exception.class}</title>
<link type="text/css" media="screen" href="#{@mount_path}/rdoc.css" rel="stylesheet">
</head>
@@ -138,10 +201,17 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
<h1>Error</h1>
<p>While processing <code>#{ERB::Util.html_escape req.request_uri}</code> the
-RDoc server has encountered a <code>#{ERB::Util.html_escape e.class}</code>
+RDoc (#{ERB::Util.html_escape RDoc::VERSION}) server has encountered a
+<code>#{ERB::Util.html_escape exception.class}</code>
exception:
-<pre>#{ERB::Util.html_escape e.message}</pre>
+<pre>#{ERB::Util.html_escape exception.message}</pre>
+
+<p>Please report this to the
+<a href="https://github.com/rdoc/rdoc/issues">RDoc issues tracker</a>. Please
+include the RDoc version, the URI above and exception class, message and
+backtrace. If you're viewing a gem's documentation, include the gem name and
+version. If you're viewing Ruby's documentation, include the version of ruby.
<p>Backtrace:
@@ -152,6 +222,9 @@ exception:
BODY
end
+ ##
+ # Instantiates a Darkfish generator for +store+
+
def generator_for store
generator = RDoc::Generator::Darkfish.new store, @options
generator.file_output = false
@@ -168,6 +241,11 @@ exception:
generator
end
+ ##
+ # Handles the If-Modified-Since HTTP header on +req+ for +path+. If the
+ # file has not been modified a Not Modified response is returned. If the
+ # file has been modified a Last-Modified header is added to +res+.
+
def if_modified_since req, res, path = nil
last_modified = File.stat(path).mtime if path
@@ -183,6 +261,14 @@ exception:
end
end
+ ##
+ # Returns an Array of installed documentation.
+ #
+ # Each entry contains the documentation name (gem name, 'Ruby
+ # Documentation', etc.), the path relative to the mount point, whether the
+ # documentation exists, the type of documentation (See RDoc::RI::Paths#each)
+ # and the filesystem to the RDoc::Store for the documentation.
+
def installed_docs
ri_paths.map do |path, type|
store = RDoc::Store.new path, type
@@ -202,15 +288,24 @@ exception:
end
end
+ ##
+ # Returns a 404 page built by +generator+ for +req+ on +res+.
+
def not_found generator, req, res
res.body = generator.generate_servlet_not_found req.path
res.status = 404
end
+ ##
+ # Enumerates the ri paths. See RDoc::RI::Paths#each
+
def ri_paths &block
RDoc::RI::Paths.each true, true, true, :all, &block
end
+ ##
+ # Generates the root page on +res+. +req+ is ignored.
+
def root req, res
generator = RDoc::Generator::Darkfish.new nil, @options
@@ -219,6 +314,9 @@ exception:
res.content_type = 'text/html'
end
+ ##
+ # Generates a search index for the root page on +res+. +req+ is ignored.
+
def root_search req, res
search_index = []
info = []
@@ -259,6 +357,10 @@ exception:
res.content_type = 'application/javascript'
end
+ ##
+ # Displays documentation for +req+ on +res+, whether that be HTML or some
+ # asset.
+
def show_documentation req, res
store, path = documentation_source req.path
@@ -280,6 +382,9 @@ exception:
res.content_type ||= 'text/html'
end
+ ##
+ # Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
+
def store_for source_name
case source_name
when 'ruby' then
diff --git a/lib/rdoc/store.rb b/lib/rdoc/store.rb
index 00c1010802..cf9ee07625 100644
--- a/lib/rdoc/store.rb
+++ b/lib/rdoc/store.rb
@@ -59,7 +59,7 @@ class RDoc::Store
@name = name
end
- def message
+ def message # :nodoc:
"store at #{@store.path} missing file #{@file} for #{@name}"
end