Sync RDoc 6.14.0

This commit is contained in:
Stan Lo 2025-05-22 22:49:04 +01:00 committed by Takashi Kokubun
parent ca1ea95784
commit 03eb777c69
185 changed files with 2008 additions and 1655 deletions

View file

@ -859,6 +859,15 @@ require 'rdoc'
# - On-page: <tt>DummyClass</tt> links to DummyClass. # - On-page: <tt>DummyClass</tt> links to DummyClass.
# - Off-page: <tt>RDoc::Alias</tt> links to RDoc::Alias. # - Off-page: <tt>RDoc::Alias</tt> links to RDoc::Alias.
# #
# Note: For poeple want to mark up code (such as class, module,
# constant, and method) as "<tt>+code+</tt>" (for interoperability
# with other MarkDown parsers mainly), such word that refers a known
# code object and is marked up entirely and separately as "monofont"
# is also converted to a link.
#
# - <tt>+DummyClass+</tt> links to DummyClass
# - <tt>+DummyClass-object+</tt> is not a link.
#
# [Module] # [Module]
# #
# - On-page: <tt>DummyModule</tt> links to DummyModule. # - On-page: <tt>DummyModule</tt> links to DummyModule.
@ -987,8 +996,7 @@ require 'rdoc'
# and entire <tt>rdoc-ref:</tt> square-bracketed clause is removed # and entire <tt>rdoc-ref:</tt> square-bracketed clause is removed
# from the resulting text. # from the resulting text.
# #
# - <tt>Nosuch[rdoc-ref:RDoc::Nosuch]</tt> generates # - <tt>Nosuch[rdoc-ref:RDoc::Nosuch]</tt> generates Nosuch.
# Nosuch[rdoc-ref:RDoc::Nosuch].
# #
# #
# [<tt>rdoc-label</tt> Scheme] # [<tt>rdoc-label</tt> Scheme]

View file

@ -21,9 +21,10 @@
# * RDoc::MetaMethod # * RDoc::MetaMethod
# * RDoc::Alias # * RDoc::Alias
# * RDoc::Constant # * RDoc::Constant
# * RDoc::Require
# * RDoc::Mixin # * RDoc::Mixin
# * RDoc::Require
# * RDoc::Include # * RDoc::Include
# * RDoc::Extend
class RDoc::CodeObject class RDoc::CodeObject
@ -89,13 +90,6 @@ class RDoc::CodeObject
attr_reader :store attr_reader :store
##
# We are the model of the code, but we know that at some point we will be
# worked on by viewers. By implementing the Viewable protocol, viewers can
# associated themselves with these objects.
attr_accessor :viewer
## ##
# When mixed-in to a class, this points to the Context in which it was originally defined. # When mixed-in to a class, this points to the Context in which it was originally defined.
@ -141,7 +135,6 @@ class RDoc::CodeObject
def comment=(comment) def comment=(comment)
@comment = case comment @comment = case comment
when NilClass then '' when NilClass then ''
when RDoc::Markup::Document then comment
when RDoc::Comment then comment.normalize when RDoc::Comment then comment.normalize
else else
if comment and not comment.empty? then if comment and not comment.empty? then
@ -217,20 +210,6 @@ class RDoc::CodeObject
@document_children = @document_self @document_children = @document_self
end end
##
# Yields each parent of this CodeObject. See also
# RDoc::ClassModule#each_ancestor
def each_parent
code_object = self
while code_object = code_object.parent do
yield code_object
end
self
end
## ##
# File name where this CodeObject was found. # File name where this CodeObject was found.
# #
@ -257,7 +236,7 @@ class RDoc::CodeObject
# #
# Set to +nil+ to clear RDoc's cached value # Set to +nil+ to clear RDoc's cached value
def full_name= full_name def full_name=(full_name)
@full_name = full_name @full_name = full_name
end end
@ -301,11 +280,7 @@ class RDoc::CodeObject
# This is used by Text#snippet # This is used by Text#snippet
def options def options
if @store and @store.rdoc then @store&.options || RDoc::Options.new
@store.rdoc.options
else
RDoc::Options.new
end
end end
## ##
@ -331,13 +306,6 @@ class RDoc::CodeObject
end end
end end
##
# File name of our parent
def parent_file_name
@parent ? @parent.base_name : '(unknown)'
end
## ##
# Name of our parent # Name of our parent
@ -348,7 +316,7 @@ class RDoc::CodeObject
## ##
# Records the RDoc::TopLevel (file) where this code object was defined # Records the RDoc::TopLevel (file) where this code object was defined
def record_location top_level def record_location(top_level)
@ignored = false @ignored = false
@suppressed = false @suppressed = false
@file = top_level @file = top_level
@ -390,7 +358,7 @@ class RDoc::CodeObject
## ##
# Sets the +store+ that contains this CodeObject # Sets the +store+ that contains this CodeObject
def store= store def store=(store)
@store = store @store = store
return unless @track_visibility return unless @track_visibility

View file

@ -23,7 +23,7 @@ class RDoc::Alias < RDoc::CodeObject
## ##
# Is this an alias declared in a singleton context? # Is this an alias declared in a singleton context?
attr_accessor :singleton attr_reader :singleton
## ##
# Source file token stream # Source file token stream
@ -34,7 +34,7 @@ class RDoc::Alias < RDoc::CodeObject
# Creates a new Alias with a token stream of +text+ that aliases +old_name+ # Creates a new Alias with a token stream of +text+ that aliases +old_name+
# to +new_name+, has +comment+ and is a +singleton+ context. # to +new_name+, has +comment+ and is a +singleton+ context.
def initialize(text, old_name, new_name, comment, singleton = false) def initialize(text, old_name, new_name, comment, singleton: false)
super() super()
@text = text @text = text
@ -59,13 +59,6 @@ class RDoc::Alias < RDoc::CodeObject
"#alias-#{type}-#{html_name}" "#alias-#{type}-#{html_name}"
end end
##
# Full old name including namespace
def full_old_name
@full_name || "#{parent.name}#{pretty_old_name}"
end
## ##
# HTML id-friendly version of +#new_name+. # HTML id-friendly version of +#new_name+.

View file

@ -29,10 +29,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr
# The section title of the method (if defined in a C file via +:category:+) # The section title of the method (if defined in a C file via +:category:+)
attr_accessor :section_title attr_accessor :section_title
# Parameters for this method
attr_accessor :params
## ##
# If true this method uses +super+ to call a superclass version # If true this method uses +super+ to call a superclass version
@ -43,8 +39,8 @@ class RDoc::AnyMethod < RDoc::MethodAttr
## ##
# Creates a new AnyMethod with a token stream +text+ and +name+ # Creates a new AnyMethod with a token stream +text+ and +name+
def initialize text, name def initialize(text, name, singleton: false)
super super(text, name, singleton: singleton)
@c_function = nil @c_function = nil
@dont_rename_initialize = false @dont_rename_initialize = false
@ -56,11 +52,10 @@ class RDoc::AnyMethod < RDoc::MethodAttr
## ##
# Adds +an_alias+ as an alias for this method in +context+. # Adds +an_alias+ as an alias for this method in +context+.
def add_alias an_alias, context = nil def add_alias(an_alias, context = nil)
method = self.class.new an_alias.text, an_alias.new_name method = self.class.new an_alias.text, an_alias.new_name, singleton: singleton
method.record_location an_alias.file method.record_location an_alias.file
method.singleton = self.singleton
method.params = self.params method.params = self.params
method.visibility = self.visibility method.visibility = self.visibility
method.comment = an_alias.comment method.comment = an_alias.comment
@ -109,8 +104,8 @@ class RDoc::AnyMethod < RDoc::MethodAttr
# #
# See also #param_seq # See also #param_seq
def call_seq= call_seq def call_seq=(call_seq)
return if call_seq.empty? return if call_seq.nil? || call_seq.empty?
@call_seq = call_seq @call_seq = call_seq
end end
@ -181,7 +176,7 @@ class RDoc::AnyMethod < RDoc::MethodAttr
# * #full_name # * #full_name
# * #parent_name # * #parent_name
def marshal_load array def marshal_load(array)
initialize_visibility initialize_visibility
@dont_rename_initialize = nil @dont_rename_initialize = nil
@ -198,7 +193,7 @@ class RDoc::AnyMethod < RDoc::MethodAttr
@full_name = array[2] @full_name = array[2]
@singleton = array[3] @singleton = array[3]
@visibility = array[4] @visibility = array[4]
@comment = array[5] @comment = RDoc::Comment.from_document array[5]
@call_seq = array[6] @call_seq = array[6]
@block_params = array[7] @block_params = array[7]
# 8 handled below # 8 handled below
@ -210,8 +205,8 @@ class RDoc::AnyMethod < RDoc::MethodAttr
@section_title = array[14] @section_title = array[14]
@is_alias_for = array[15] @is_alias_for = array[15]
array[8].each do |new_name, comment| array[8].each do |new_name, document|
add_alias RDoc::Alias.new(nil, @name, new_name, comment, @singleton) add_alias RDoc::Alias.new(nil, @name, new_name, RDoc::Comment.from_document(document), singleton: @singleton)
end end
@parent_name ||= if @full_name =~ /#/ then @parent_name ||= if @full_name =~ /#/ then
@ -314,7 +309,7 @@ class RDoc::AnyMethod < RDoc::MethodAttr
## ##
# Sets the store for this method and its referenced code objects. # Sets the store for this method and its referenced code objects.
def store= store def store=(store)
super super
@file = @store.add_file @file.full_name if @file @file = @store.add_file @file.full_name if @file

View file

@ -22,18 +22,17 @@ class RDoc::Attr < RDoc::MethodAttr
# Creates a new Attr with body +text+, +name+, read/write status +rw+ and # Creates a new Attr with body +text+, +name+, read/write status +rw+ and
# +comment+. +singleton+ marks this as a class attribute. # +comment+. +singleton+ marks this as a class attribute.
def initialize(text, name, rw, comment, singleton = false) def initialize(text, name, rw, comment, singleton: false)
super text, name super(text, name, singleton: singleton)
@rw = rw @rw = rw
@singleton = singleton
self.comment = comment self.comment = comment
end end
## ##
# Attributes are equal when their names, singleton and rw are identical # Attributes are equal when their names, singleton and rw are identical
def == other def ==(other)
self.class == other.class and self.class == other.class and
self.name == other.name and self.name == other.name and
self.rw == other.rw and self.rw == other.rw and
@ -44,9 +43,7 @@ class RDoc::Attr < RDoc::MethodAttr
# Add +an_alias+ as an attribute in +context+. # Add +an_alias+ as an attribute in +context+.
def add_alias(an_alias, context) def add_alias(an_alias, context)
new_attr = self.class.new(self.text, an_alias.new_name, self.rw, new_attr = self.class.new(text, an_alias.new_name, rw, comment, singleton: singleton)
self.comment, self.singleton)
new_attr.record_location an_alias.file new_attr.record_location an_alias.file
new_attr.visibility = self.visibility new_attr.visibility = self.visibility
new_attr.is_alias_for = self new_attr.is_alias_for = self
@ -121,7 +118,7 @@ class RDoc::Attr < RDoc::MethodAttr
# * #full_name # * #full_name
# * #parent_name # * #parent_name
def marshal_load array def marshal_load(array)
initialize_visibility initialize_visibility
@aliases = [] @aliases = []
@ -136,7 +133,7 @@ class RDoc::Attr < RDoc::MethodAttr
@full_name = array[2] @full_name = array[2]
@rw = array[3] @rw = array[3]
@visibility = array[4] @visibility = array[4]
@comment = array[5] @comment = RDoc::Comment.from_document array[5]
@singleton = array[6] || false # MARSHAL_VERSION == 0 @singleton = array[6] || false # MARSHAL_VERSION == 0
# 7 handled below # 7 handled below
@parent_name = array[8] @parent_name = array[8]
@ -148,7 +145,7 @@ class RDoc::Attr < RDoc::MethodAttr
@parent_name ||= @full_name.split('#', 2).first @parent_name ||= @full_name.split('#', 2).first
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[#{self.class.name} #{full_name} #{rw} #{visibility}", "]" do q.group 2, "[#{self.class.name} #{full_name} #{rw} #{visibility}", "]" do
unless comment.empty? then unless comment.empty? then
q.breakable q.breakable

View file

@ -34,8 +34,6 @@ class RDoc::ClassModule < RDoc::Context
attr_accessor :comment_location attr_accessor :comment_location
attr_accessor :diagram # :nodoc:
## ##
# Class or module this constant is an alias for # Class or module this constant is an alias for
@ -47,7 +45,7 @@ class RDoc::ClassModule < RDoc::Context
#-- #--
# TODO move to RDoc::NormalClass (I think) # TODO move to RDoc::NormalClass (I think)
def self.from_module class_type, mod def self.from_module(class_type, mod)
klass = class_type.new mod.name klass = class_type.new mod.name
mod.comment_location.each do |comment, location| mod.comment_location.each do |comment, location|
@ -56,7 +54,6 @@ class RDoc::ClassModule < RDoc::Context
klass.parent = mod.parent klass.parent = mod.parent
klass.section = mod.section klass.section = mod.section
klass.viewer = mod.viewer
klass.attributes.concat mod.attributes klass.attributes.concat mod.attributes
klass.method_list.concat mod.method_list klass.method_list.concat mod.method_list
@ -110,7 +107,6 @@ class RDoc::ClassModule < RDoc::Context
def initialize(name, superclass = nil) def initialize(name, superclass = nil)
@constant_aliases = [] @constant_aliases = []
@diagram = nil
@is_alias_for = nil @is_alias_for = nil
@name = name @name = name
@superclass = superclass @superclass = superclass
@ -124,7 +120,7 @@ class RDoc::ClassModule < RDoc::Context
# method is preferred over #comment= since it allows ri data to be updated # method is preferred over #comment= since it allows ri data to be updated
# across multiple runs. # across multiple runs.
def add_comment comment, location def add_comment(comment, location)
return unless document_self return unless document_self
original = comment original = comment
@ -145,7 +141,7 @@ class RDoc::ClassModule < RDoc::Context
self.comment = original self.comment = original
end end
def add_things my_things, other_things # :nodoc: def add_things(my_things, other_things) # :nodoc:
other_things.each do |group, things| other_things.each do |group, things|
my_things[group].each { |thing| yield false, thing } if my_things[group].each { |thing| yield false, thing } if
my_things.include? group my_things.include? group
@ -202,7 +198,7 @@ class RDoc::ClassModule < RDoc::Context
# Appends +comment+ to the current comment, but separated by a rule. Works # Appends +comment+ to the current comment, but separated by a rule. Works
# more like <tt>+=</tt>. # more like <tt>+=</tt>.
def comment= comment # :nodoc: def comment=(comment) # :nodoc:
comment = case comment comment = case comment
when RDoc::Comment then when RDoc::Comment then
comment.normalize comment.normalize
@ -220,11 +216,12 @@ class RDoc::ClassModule < RDoc::Context
# #
# See RDoc::Store#complete # See RDoc::Store#complete
def complete min_visibility def complete(min_visibility)
update_aliases update_aliases
remove_nodoc_children remove_nodoc_children
embed_mixins embed_mixins
update_includes update_includes
update_extends
remove_invisible min_visibility remove_invisible min_visibility
end end
@ -262,7 +259,7 @@ class RDoc::ClassModule < RDoc::Context
## ##
# Looks for a symbol in the #ancestors. See Context#find_local_symbol. # Looks for a symbol in the #ancestors. See Context#find_local_symbol.
def find_ancestor_local_symbol symbol def find_ancestor_local_symbol(symbol)
each_ancestor do |m| each_ancestor do |m|
res = m.find_local_symbol(symbol) res = m.find_local_symbol(symbol)
return res if res return res if res
@ -274,7 +271,7 @@ class RDoc::ClassModule < RDoc::Context
## ##
# Finds a class or module with +name+ in this namespace or its descendants # Finds a class or module with +name+ in this namespace or its descendants
def find_class_named name def find_class_named(name)
return self if full_name == name return self if full_name == name
return self if @name == name return self if @name == name
@ -295,6 +292,25 @@ class RDoc::ClassModule < RDoc::Context
end end
end end
##
# Return array of full_name splitted by +::+.
def nesting_namespaces
@namespaces ||= full_name.split("::").reject(&:empty?)
end
##
# Return array of fully qualified nesting namespaces.
#
# For example, if full_name is +A::B::C+, this method returns <code>["A", "A::B", "A::B::C"]</code>
def fully_qualified_nesting_namespaces
return nesting_namespaces if nesting_namespaces.length < 2
@fqns ||= nesting_namespaces.inject([]) do |list, n|
list << (list.empty? ? n : "#{list.last}::#{n}")
end
end
## ##
# TODO: filter included items by #display? # TODO: filter included items by #display?
@ -344,7 +360,7 @@ class RDoc::ClassModule < RDoc::Context
] ]
end end
def marshal_load array # :nodoc: def marshal_load(array) # :nodoc:
initialize_visibility initialize_visibility
initialize_methods_etc initialize_methods_etc
@current_section = nil @current_section = nil
@ -359,37 +375,39 @@ class RDoc::ClassModule < RDoc::Context
@name = array[1] @name = array[1]
@full_name = array[2] @full_name = array[2]
@superclass = array[3] @superclass = array[3]
@comment = array[4] document = array[4]
@comment_location = if RDoc::Markup::Document === @comment.parts.first then @comment = RDoc::Comment.from_document document
@comment
@comment_location = if RDoc::Markup::Document === document.parts.first then
document
else else
RDoc::Markup::Document.new @comment RDoc::Markup::Document.new document
end end
array[5].each do |name, rw, visibility, singleton, file| array[5].each do |name, rw, visibility, singleton, file|
singleton ||= false singleton ||= false
visibility ||= :public visibility ||= :public
attr = RDoc::Attr.new nil, name, rw, nil, singleton attr = RDoc::Attr.new nil, name, rw, nil, singleton: singleton
add_attribute attr add_attribute attr
attr.visibility = visibility attr.visibility = visibility
attr.record_location RDoc::TopLevel.new file attr.record_location RDoc::TopLevel.new file
end end
array[6].each do |constant, comment, file| array[6].each do |constant, document, file|
case constant case constant
when RDoc::Constant then when RDoc::Constant then
add_constant constant add_constant constant
else else
constant = add_constant RDoc::Constant.new(constant, nil, comment) constant = add_constant RDoc::Constant.new(constant, nil, RDoc::Comment.from_document(document))
constant.record_location RDoc::TopLevel.new file constant.record_location RDoc::TopLevel.new file
end end
end end
array[7].each do |name, comment, file| array[7].each do |name, document, file|
incl = add_include RDoc::Include.new(name, comment) incl = add_include RDoc::Include.new(name, RDoc::Comment.from_document(document))
incl.record_location RDoc::TopLevel.new file incl.record_location RDoc::TopLevel.new file
end end
@ -398,16 +416,15 @@ class RDoc::ClassModule < RDoc::Context
@visibility = visibility @visibility = visibility
methods.each do |name, file| methods.each do |name, file|
method = RDoc::AnyMethod.new nil, name method = RDoc::AnyMethod.new nil, name, singleton: type == 'class'
method.singleton = true if type == 'class'
method.record_location RDoc::TopLevel.new file method.record_location RDoc::TopLevel.new file
add_method method add_method method
end end
end end
end end
array[9].each do |name, comment, file| array[9].each do |name, document, file|
ext = add_extend RDoc::Extend.new(name, comment) ext = add_extend RDoc::Extend.new(name, RDoc::Comment.from_document(document))
ext.record_location RDoc::TopLevel.new file ext.record_location RDoc::TopLevel.new file
end if array[9] # Support Marshal version 1 end if array[9] # Support Marshal version 1
@ -433,7 +450,7 @@ class RDoc::ClassModule < RDoc::Context
# #
# The data in +class_module+ is preferred over the receiver. # The data in +class_module+ is preferred over the receiver.
def merge class_module def merge(class_module)
@parent = class_module.parent @parent = class_module.parent
@parent_name = class_module.parent_name @parent_name = class_module.parent_name
@ -444,7 +461,8 @@ class RDoc::ClassModule < RDoc::Context
document = document.merge other_document document = document.merge other_document
@comment = @comment_location = document @comment = RDoc::Comment.from_document(document)
@comment_location = document
end end
cm = class_module cm = class_module
@ -517,7 +535,7 @@ class RDoc::ClassModule < RDoc::Context
# end # end
# end # end
def merge_collections mine, other, other_files, &block # :nodoc: def merge_collections(mine, other, other_files, &block) # :nodoc:
my_things = mine. group_by { |thing| thing.file } my_things = mine. group_by { |thing| thing.file }
other_things = other.group_by { |thing| thing.file } other_things = other.group_by { |thing| thing.file }
@ -529,7 +547,7 @@ class RDoc::ClassModule < RDoc::Context
# Merges the comments in this ClassModule with the comments in the other # Merges the comments in this ClassModule with the comments in the other
# ClassModule +cm+. # ClassModule +cm+.
def merge_sections cm # :nodoc: def merge_sections(cm) # :nodoc:
my_sections = sections.group_by { |section| section.title } my_sections = sections.group_by { |section| section.title }
other_sections = cm.sections.group_by { |section| section.title } other_sections = cm.sections.group_by { |section| section.title }
@ -577,7 +595,7 @@ class RDoc::ClassModule < RDoc::Context
# #
# Used for modules and classes that are constant aliases. # Used for modules and classes that are constant aliases.
def name= new_name def name=(new_name)
@name = new_name @name = new_name
end end
@ -585,7 +603,7 @@ class RDoc::ClassModule < RDoc::Context
# Parses +comment_location+ into an RDoc::Markup::Document composed of # Parses +comment_location+ into an RDoc::Markup::Document composed of
# multiple RDoc::Markup::Documents with their file set. # multiple RDoc::Markup::Documents with their file set.
def parse comment_location def parse(comment_location)
case comment_location case comment_location
when String then when String then
super super
@ -612,7 +630,9 @@ class RDoc::ClassModule < RDoc::Context
# Path to this class or module for use with HTML generator output. # Path to this class or module for use with HTML generator output.
def path def path
http_url @store.rdoc.generator.class_dir prefix = options.class_module_path_prefix
return http_url unless prefix
File.join(prefix, http_url)
end end
## ##
@ -655,7 +675,7 @@ class RDoc::ClassModule < RDoc::Context
end end
end end
def remove_things my_things, other_files # :nodoc: def remove_things(my_things, other_files) # :nodoc:
my_things.delete_if do |file, things| my_things.delete_if do |file, things|
next false unless other_files.include? file next false unless other_files.include? file
@ -685,7 +705,7 @@ class RDoc::ClassModule < RDoc::Context
## ##
# Sets the store for this class or module and its contained code objects. # Sets the store for this class or module and its contained code objects.
def store= store def store=(store)
super super
@attributes .each do |attr| attr.store = store end @attributes .each do |attr| attr.store = store end

View file

@ -44,7 +44,7 @@ class RDoc::Constant < RDoc::CodeObject
## ##
# Constants are ordered by name # Constants are ordered by name
def <=> other def <=>(other)
return unless self.class === other return unless self.class === other
[parent_name, name] <=> [other.parent_name, other.name] [parent_name, name] <=> [other.parent_name, other.name]
@ -53,7 +53,7 @@ class RDoc::Constant < RDoc::CodeObject
## ##
# Constants are equal when their #parent and #name is the same # Constants are equal when their #parent and #name is the same
def == other def ==(other)
self.class == other.class and self.class == other.class and
@parent == other.parent and @parent == other.parent and
@name == other.name @name == other.name
@ -132,8 +132,8 @@ class RDoc::Constant < RDoc::CodeObject
# * #full_name # * #full_name
# * #parent_name # * #parent_name
def marshal_load array def marshal_load(array)
initialize array[1], nil, array[5] initialize array[1], nil, RDoc::Comment.from_document(array[5])
@full_name = array[2] @full_name = array[2]
@visibility = array[3] || :public @visibility = array[3] || :public
@ -154,7 +154,7 @@ class RDoc::Constant < RDoc::CodeObject
"#{@parent.path}##{@name}" "#{@parent.path}##{@name}"
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[#{self.class.name} #{full_name}", "]" do q.group 2, "[#{self.class.name} #{full_name}", "]" do
unless comment.empty? then unless comment.empty? then
q.breakable q.breakable
@ -168,7 +168,7 @@ class RDoc::Constant < RDoc::CodeObject
## ##
# Sets the store for this class or module and its contained code objects. # Sets the store for this class or module and its contained code objects.
def store= store def store=(store)
super super
@file = @store.add_file @file.full_name if @file @file = @store.add_file @file.full_name if @file

View file

@ -180,7 +180,7 @@ class RDoc::Context < RDoc::CodeObject
# #
# Currently only RDoc::Extend and RDoc::Include are supported. # Currently only RDoc::Extend and RDoc::Include are supported.
def add klass, name, comment def add(klass, name, comment)
if RDoc::Extend == klass then if RDoc::Extend == klass then
ext = RDoc::Extend.new name, comment ext = RDoc::Extend.new name, comment
add_extend ext add_extend ext
@ -195,7 +195,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Adds +an_alias+ that is automatically resolved # Adds +an_alias+ that is automatically resolved
def add_alias an_alias def add_alias(an_alias)
return an_alias unless @document_self return an_alias unless @document_self
method_attr = find_method(an_alias.old_name, an_alias.singleton) || method_attr = find_method(an_alias.old_name, an_alias.singleton) ||
@ -222,7 +222,7 @@ class RDoc::Context < RDoc::CodeObject
# if method +foo+ exists, but <tt>attr_accessor :foo</tt> will be registered # if method +foo+ exists, but <tt>attr_accessor :foo</tt> will be registered
# if method +foo+ exists, but <tt>foo=</tt> does not. # if method +foo+ exists, but <tt>foo=</tt> does not.
def add_attribute attribute def add_attribute(attribute)
return attribute unless @document_self return attribute unless @document_self
# mainly to check for redefinition of an attribute as a method # mainly to check for redefinition of an attribute as a method
@ -285,7 +285,7 @@ class RDoc::Context < RDoc::CodeObject
# unless it later sees <tt>class Container</tt>. +add_class+ automatically # unless it later sees <tt>class Container</tt>. +add_class+ automatically
# upgrades +given_name+ to a class in this case. # upgrades +given_name+ to a class in this case.
def add_class class_type, given_name, superclass = '::Object' def add_class(class_type, given_name, superclass = '::Object')
# superclass +nil+ is passed by the C parser in the following cases: # superclass +nil+ is passed by the C parser in the following cases:
# - registering Object in 1.8 (correct) # - registering Object in 1.8 (correct)
# - registering BasicObject in 1.9 (correct) # - registering BasicObject in 1.9 (correct)
@ -401,7 +401,7 @@ class RDoc::Context < RDoc::CodeObject
# unless #done_documenting is +true+. Sets the #parent of +mod+ # unless #done_documenting is +true+. Sets the #parent of +mod+
# to +self+, and its #section to #current_section. Returns +mod+. # to +self+, and its #section to #current_section. Returns +mod+.
def add_class_or_module mod, self_hash, all_hash def add_class_or_module(mod, self_hash, all_hash)
mod.section = current_section # TODO declaring context? something is mod.section = current_section # TODO declaring context? something is
# wrong here... # wrong here...
mod.parent = self mod.parent = self
@ -426,7 +426,7 @@ class RDoc::Context < RDoc::CodeObject
# Adds +constant+ if not already there. If it is, updates the comment, # Adds +constant+ if not already there. If it is, updates the comment,
# value and/or is_alias_for of the known constant if they were empty/nil. # value and/or is_alias_for of the known constant if they were empty/nil.
def add_constant constant def add_constant(constant)
return constant unless @document_self return constant unless @document_self
# HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code) # HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code)
@ -451,7 +451,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Adds included module +include+ which should be an RDoc::Include # Adds included module +include+ which should be an RDoc::Include
def add_include include def add_include(include)
add_to @includes, include add_to @includes, include
include include
@ -460,7 +460,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Adds extension module +ext+ which should be an RDoc::Extend # Adds extension module +ext+ which should be an RDoc::Extend
def add_extend ext def add_extend(ext)
add_to @extends, ext add_to @extends, ext
ext ext
@ -470,7 +470,7 @@ class RDoc::Context < RDoc::CodeObject
# Adds +method+ if not already there. If it is (as method or attribute), # Adds +method+ if not already there. If it is (as method or attribute),
# updates the comment if it was empty. # updates the comment if it was empty.
def add_method method def add_method(method)
return method unless @document_self return method unless @document_self
# HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code) # HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code)
@ -482,7 +482,7 @@ class RDoc::Context < RDoc::CodeObject
known.comment = method.comment if known.comment.empty? known.comment = method.comment if known.comment.empty?
previously = ", previously in #{known.file}" unless previously = ", previously in #{known.file}" unless
method.file == known.file method.file == known.file
@store.rdoc.options.warn \ @store.options.warn \
"Duplicate method #{known.full_name} in #{method.file}#{previously}" "Duplicate method #{known.full_name} in #{method.file}#{previously}"
end end
else else
@ -524,7 +524,7 @@ class RDoc::Context < RDoc::CodeObject
# Adds an alias from +from+ (a class or module) to +name+ which was defined # Adds an alias from +from+ (a class or module) to +name+ which was defined
# in +file+. # in +file+.
def add_module_alias from, from_name, to, file def add_module_alias(from, from_name, to, file)
return from if @done_documenting return from if @done_documenting
to_full_name = child_name to.name to_full_name = child_name to.name
@ -583,7 +583,7 @@ class RDoc::Context < RDoc::CodeObject
# #
# See also RDoc::Context::Section # See also RDoc::Context::Section
def add_section title, comment = nil def add_section(title, comment = nil)
if section = @sections[title] then if section = @sections[title] then
section.add_comment comment if comment section.add_comment comment if comment
else else
@ -597,7 +597,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Adds +thing+ to the collection +array+ # Adds +thing+ to the collection +array+
def add_to array, thing def add_to(array, thing)
array << thing if @document_self array << thing if @document_self
thing.parent = self thing.parent = self
@ -629,7 +629,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Creates the full name for a child with +name+ # Creates the full name for a child with +name+
def child_name name def child_name(name)
if name =~ /^:+/ if name =~ /^:+/
$' #' $' #'
elsif RDoc::TopLevel === self then elsif RDoc::TopLevel === self then
@ -688,13 +688,6 @@ class RDoc::Context < RDoc::CodeObject
section section
end end
##
# Is part of this thing was defined in +file+?
def defined_in?(file)
@in_files.include?(file)
end
def display(method_attr) # :nodoc: def display(method_attr) # :nodoc:
if method_attr.is_a? RDoc::Attr if method_attr.is_a? RDoc::Attr
"#{method_attr.definition} #{method_attr.pretty_name}" "#{method_attr.definition} #{method_attr.pretty_name}"
@ -713,13 +706,6 @@ class RDoc::Context < RDoc::CodeObject
def each_ancestor(&_) # :nodoc: def each_ancestor(&_) # :nodoc:
end end
##
# Iterator for attributes
def each_attribute # :yields: attribute
@attributes.each { |a| yield a }
end
## ##
# Iterator for classes and modules # Iterator for classes and modules
@ -727,27 +713,6 @@ class RDoc::Context < RDoc::CodeObject
classes_and_modules.sort.each(&block) classes_and_modules.sort.each(&block)
end end
##
# Iterator for constants
def each_constant # :yields: constant
@constants.each {|c| yield c}
end
##
# Iterator for included modules
def each_include # :yields: include
@includes.each do |i| yield i end
end
##
# Iterator for extension modules
def each_extend # :yields: extend
@extends.each do |e| yield e end
end
## ##
# Iterator for methods # Iterator for methods
@ -847,13 +812,6 @@ class RDoc::Context < RDoc::CodeObject
end end
end end
##
# Finds a file with +name+ in this context
def find_file_named name
@store.find_file_named name
end
## ##
# Finds an instance method with +name+ in this context # Finds an instance method with +name+ in this context
@ -871,7 +829,7 @@ class RDoc::Context < RDoc::CodeObject
find_attribute_named(symbol) or find_attribute_named(symbol) or
find_external_alias_named(symbol) or find_external_alias_named(symbol) or
find_module_named(symbol) or find_module_named(symbol) or
find_file_named(symbol) @store.find_file_named(symbol)
end end
## ##
@ -973,10 +931,10 @@ class RDoc::Context < RDoc::CodeObject
## ##
# URL for this with a +prefix+ # URL for this with a +prefix+
def http_url(prefix) def http_url
path = name_for_path path = name_for_path
path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /<</ path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /<</
path = [prefix] + path.split('::') path = path.split('::')
File.join(*path.compact) + '.html' File.join(*path.compact) + '.html'
end end
@ -1012,7 +970,7 @@ class RDoc::Context < RDoc::CodeObject
# If +section+ is provided only methods in that RDoc::Context::Section will # If +section+ is provided only methods in that RDoc::Context::Section will
# be returned. # be returned.
def methods_by_type section = nil def methods_by_type(section = nil)
methods = {} methods = {}
TYPES.each do |type| TYPES.each do |type|
@ -1104,7 +1062,7 @@ class RDoc::Context < RDoc::CodeObject
#-- #--
# TODO mark the visibility of attributes in the template (if not public?) # TODO mark the visibility of attributes in the template (if not public?)
def remove_invisible min_visibility def remove_invisible(min_visibility)
return if [:private, :nodoc].include? min_visibility return if [:private, :nodoc].include? min_visibility
remove_invisible_in @method_list, min_visibility remove_invisible_in @method_list, min_visibility
remove_invisible_in @attributes, min_visibility remove_invisible_in @attributes, min_visibility
@ -1114,7 +1072,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Only called when min_visibility == :public or :private # Only called when min_visibility == :public or :private
def remove_invisible_in array, min_visibility # :nodoc: def remove_invisible_in(array, min_visibility) # :nodoc:
if min_visibility == :public then if min_visibility == :public then
array.reject! { |e| array.reject! { |e|
e.visibility != :public and not e.force_documentation e.visibility != :public and not e.force_documentation
@ -1130,7 +1088,7 @@ class RDoc::Context < RDoc::CodeObject
# Tries to resolve unmatched aliases when a method or attribute has just # Tries to resolve unmatched aliases when a method or attribute has just
# been added. # been added.
def resolve_aliases added def resolve_aliases(added)
# resolve any pending unmatched aliases # resolve any pending unmatched aliases
key = added.pretty_name key = added.pretty_name
unmatched_alias_list = @unmatched_alias_lists[key] unmatched_alias_list = @unmatched_alias_lists[key]
@ -1181,7 +1139,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Sets the current section to a section with +title+. See also #add_section # Sets the current section to a section with +title+. See also #add_section
def set_current_section title, comment def set_current_section(title, comment)
@current_section = add_section title, comment @current_section = add_section title, comment
end end
@ -1246,7 +1204,7 @@ class RDoc::Context < RDoc::CodeObject
## ##
# Upgrades NormalModule +mod+ in +enclosing+ to a +class_type+ # Upgrades NormalModule +mod+ in +enclosing+ to a +class_type+
def upgrade_to_class mod, class_type, enclosing def upgrade_to_class(mod, class_type, enclosing)
enclosing.modules_hash.delete mod.name enclosing.modules_hash.delete mod.name
klass = RDoc::ClassModule.from_module class_type, mod klass = RDoc::ClassModule.from_module class_type, mod

View file

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'cgi/util' require 'cgi/escape'
## ##
# A section of documentation like: # A section of documentation like:
@ -39,7 +39,7 @@ class RDoc::Context::Section
## ##
# Creates a new section with +title+ and +comment+ # Creates a new section with +title+ and +comment+
def initialize parent, title, comment def initialize(parent, title, comment)
@parent = parent @parent = parent
@title = title ? title.strip : title @title = title ? title.strip : title
@ -51,7 +51,7 @@ class RDoc::Context::Section
## ##
# Sections are equal when they have the same #title # Sections are equal when they have the same #title
def == other def ==(other)
self.class === other and @title == other.title self.class === other and @title == other.title
end end
@ -60,20 +60,11 @@ class RDoc::Context::Section
## ##
# Adds +comment+ to this section # Adds +comment+ to this section
def add_comment comment def add_comment(comment)
comment = extract_comment comment comments = Array(comment)
comments.each do |c|
return if comment.empty? extracted_comment = extract_comment(c)
@comments << extracted_comment unless extracted_comment.empty?
case comment
when RDoc::Comment then
@comments << comment
when RDoc::Markup::Document then
@comments.concat comment.parts
when Array then
@comments.concat comment
else
raise TypeError, "unknown comment type: #{comment.inspect}"
end end
end end
@ -95,12 +86,8 @@ class RDoc::Context::Section
# # :section: The title # # :section: The title
# # The body # # The body
def extract_comment comment def extract_comment(comment)
case comment case comment
when Array then
comment.map do |c|
extract_comment c
end
when nil when nil
RDoc::Comment.new '' RDoc::Comment.new ''
when RDoc::Comment then when RDoc::Comment then
@ -115,8 +102,6 @@ class RDoc::Context::Section
end end
end end
comment
when RDoc::Markup::Document then
comment comment
else else
raise TypeError, "unknown comment #{comment.inspect}" raise TypeError, "unknown comment #{comment.inspect}"
@ -135,20 +120,7 @@ class RDoc::Context::Section
# The files comments in this section come from # The files comments in this section come from
def in_files def in_files
return [] if @comments.empty? @comments.map(&:file)
case @comments
when Array then
@comments.map do |comment|
comment.file
end
when RDoc::Markup::Document then
@comment.parts.map do |document|
document.file
end
else
raise RDoc::Error, "BUG: unknown comment class #{@comments.class}"
end
end end
## ##
@ -166,11 +138,11 @@ class RDoc::Context::Section
## ##
# De-serializes this Section. The section parent must be restored manually. # De-serializes this Section. The section parent must be restored manually.
def marshal_load array def marshal_load(array)
@parent = nil @parent = nil
@title = array[1] @title = array[1]
@comments = array[2] @comments = array[2].parts.map { |doc| RDoc::Comment.from_document(doc) }
end end
## ##
@ -178,26 +150,7 @@ class RDoc::Context::Section
# multiple RDoc::Markup::Documents with their file set. # multiple RDoc::Markup::Documents with their file set.
def parse def parse
case @comments RDoc::Markup::Document.new(*@comments.map(&:parse))
when String then
super
when Array then
docs = @comments.map do |comment, location|
doc = super comment
doc.file = location if location
doc
end
RDoc::Markup::Document.new(*docs)
when RDoc::Comment then
doc = super @comments.text, comments.format
doc.file = @comments.location
doc
when RDoc::Markup::Document then
return @comments
else
raise ArgumentError, "unknown comment class #{comments.class}"
end
end end
## ##
@ -213,20 +166,9 @@ class RDoc::Context::Section
# Removes a comment from this section if it is from the same file as # Removes a comment from this section if it is from the same file as
# +comment+ # +comment+
def remove_comment comment def remove_comment(target_comment)
return if @comments.empty? @comments.delete_if do |stored_comment|
stored_comment.file == target_comment.file
case @comments
when Array then
@comments.delete_if do |my_comment|
my_comment.file == comment.file
end
when RDoc::Markup::Document then
@comments.parts.delete_if do |document|
document.file == comment.file.name
end
else
raise RDoc::Error, "BUG: unknown comment class #{@comments.class}"
end end
end end

View file

@ -63,19 +63,13 @@ class RDoc::MethodAttr < RDoc::CodeObject
attr_reader :arglists attr_reader :arglists
##
# Pretty parameter list for this method
attr_reader :param_seq
## ##
# Creates a new MethodAttr from token stream +text+ and method or attribute # Creates a new MethodAttr from token stream +text+ and method or attribute
# name +name+. # name +name+.
# #
# Usually this is called by super from a subclass. # Usually this is called by super from a subclass.
def initialize text, name def initialize(text, name, singleton: false)
super() super()
@text = text @text = text
@ -84,21 +78,20 @@ class RDoc::MethodAttr < RDoc::CodeObject
@aliases = [] @aliases = []
@is_alias_for = nil @is_alias_for = nil
@parent_name = nil @parent_name = nil
@singleton = nil @singleton = singleton
@visibility = :public @visibility = :public
@see = false @see = false
@arglists = nil @arglists = nil
@block_params = nil @block_params = nil
@call_seq = nil @call_seq = nil
@param_seq = nil
@params = nil @params = nil
end end
## ##
# Resets cached data for the object so it can be rebuilt by accessor methods # Resets cached data for the object so it can be rebuilt by accessor methods
def initialize_copy other # :nodoc: def initialize_copy(other) # :nodoc:
@full_name = nil @full_name = nil
end end
@ -118,7 +111,7 @@ class RDoc::MethodAttr < RDoc::CodeObject
[other.singleton ? 0 : 1, other.name_ord_range, other.name] [other.singleton ? 0 : 1, other.name_ord_range, other.name]
end end
def == other # :nodoc: def ==(other) # :nodoc:
equal?(other) or self.class == other.class and full_name == other.full_name equal?(other) or self.class == other.class and full_name == other.full_name
end end
@ -157,7 +150,7 @@ class RDoc::MethodAttr < RDoc::CodeObject
## ##
# Sets the store for this class or module and its contained code objects. # Sets the store for this class or module and its contained code objects.
def store= store def store=(store)
super super
@file = @store.add_file @file.full_name if @file @file = @store.add_file @file.full_name if @file
@ -175,7 +168,7 @@ class RDoc::MethodAttr < RDoc::CodeObject
return find_method_or_attribute name[0..-2] return find_method_or_attribute name[0..-2]
end end
def find_method_or_attribute name # :nodoc: def find_method_or_attribute(name) # :nodoc:
return nil unless parent.respond_to? :ancestors return nil unless parent.respond_to? :ancestors
searched = parent.ancestors searched = parent.ancestors
@ -289,7 +282,7 @@ class RDoc::MethodAttr < RDoc::CodeObject
# HTML id-friendly method/attribute name # HTML id-friendly method/attribute name
def html_name def html_name
require 'cgi/util' require 'cgi/escape'
CGI.escape(@name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '') CGI.escape(@name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '')
end end
@ -320,19 +313,6 @@ class RDoc::MethodAttr < RDoc::CodeObject
@singleton ? '::' : '#' @singleton ? '::' : '#'
end end
##
# Name for output to HTML. For class methods the full name with a "." is
# used like +SomeClass.method_name+. For instance methods the class name is
# used if +context+ does not match the parent.
#
# This is to help prevent people from using :: to call class methods.
def output_name context
return "#{name_prefix}#{@name}" if context == parent
"#{parent_name}#{@singleton ? '.' : '#'}#{@name}"
end
## ##
# Method/attribute name with class/instance indicator # Method/attribute name with class/instance indicator
@ -361,7 +341,7 @@ class RDoc::MethodAttr < RDoc::CodeObject
@parent_name || super @parent_name || super
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
alias_for = alias_for =
if @is_alias_for.respond_to? :name then if @is_alias_for.respond_to? :name then
"alias for #{@is_alias_for.name}" "alias for #{@is_alias_for.name}"

View file

@ -23,13 +23,13 @@ class RDoc::Mixin < RDoc::CodeObject
## ##
# Mixins are sorted by name # Mixins are sorted by name
def <=> other def <=>(other)
return unless self.class === other return unless self.class === other
name <=> other.name name <=> other.name
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class === other and @name == other.name self.class === other and @name == other.name
end end
@ -107,7 +107,7 @@ class RDoc::Mixin < RDoc::CodeObject
## ##
# Sets the store for this class or module and its contained code objects. # Sets the store for this class or module and its contained code objects.
def store= store def store=(store)
super super
@file = @store.add_file @file.full_name if @file @file = @store.add_file @file.full_name if @file

View file

@ -53,7 +53,7 @@ class RDoc::NormalClass < RDoc::ClassModule
display display
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
superclass = @superclass ? " < #{@superclass}" : nil superclass = @superclass ? " < #{@superclass}" : nil
q.group 2, "[class #{full_name}#{superclass}", "]" do q.group 2, "[class #{full_name}#{superclass}", "]" do

View file

@ -29,7 +29,7 @@ class RDoc::NormalModule < RDoc::ClassModule
true true
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[module #{full_name}:", "]" do q.group 2, "[module #{full_name}:", "]" do
q.breakable q.breakable
q.text "includes:" q.text "includes:"

View file

@ -24,7 +24,7 @@ class RDoc::Require < RDoc::CodeObject
self.class, self.class,
object_id, object_id,
@name, @name,
parent_file_name, @parent ? @parent.base_name : '(unknown)'
] ]
end end

View file

@ -22,7 +22,7 @@ class RDoc::SingleClass < RDoc::ClassModule
"class << #{full_name}" "class << #{full_name}"
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[class << #{full_name}", "]" do q.group 2, "[class << #{full_name}", "]" do
next next
end end

View file

@ -6,11 +6,6 @@ class RDoc::TopLevel < RDoc::Context
MARSHAL_VERSION = 0 # :nodoc: MARSHAL_VERSION = 0 # :nodoc:
##
# This TopLevel's File::Stat struct
attr_accessor :file_stat
## ##
# Relative name of this file # Relative name of this file
@ -28,8 +23,6 @@ class RDoc::TopLevel < RDoc::Context
attr_reader :classes_or_modules attr_reader :classes_or_modules
attr_accessor :diagram # :nodoc:
## ##
# The parser class that processed this file # The parser class that processed this file
@ -40,13 +33,11 @@ class RDoc::TopLevel < RDoc::Context
# is being generated outside the source dir +relative_name+ is relative to # is being generated outside the source dir +relative_name+ is relative to
# the source directory. # the source directory.
def initialize absolute_name, relative_name = absolute_name def initialize(absolute_name, relative_name = absolute_name)
super() super()
@name = nil @name = nil
@absolute_name = absolute_name @absolute_name = absolute_name
@relative_name = relative_name @relative_name = relative_name
@file_stat = File.stat(absolute_name) rescue nil # HACK for testing
@diagram = nil
@parser = nil @parser = nil
@classes_or_modules = [] @classes_or_modules = []
@ -64,7 +55,7 @@ class RDoc::TopLevel < RDoc::Context
## ##
# An RDoc::TopLevel is equal to another with the same relative_name # An RDoc::TopLevel is equal to another with the same relative_name
def == other def ==(other)
self.class === other and @relative_name == other.relative_name self.class === other and @relative_name == other.relative_name
end end
@ -82,7 +73,7 @@ class RDoc::TopLevel < RDoc::Context
## ##
# Adds +constant+ to +Object+ instead of +self+. # Adds +constant+ to +Object+ instead of +self+.
def add_constant constant def add_constant(constant)
object_class.record_location self object_class.record_location self
return constant unless @document_self return constant unless @document_self
object_class.add_constant constant object_class.add_constant constant
@ -110,7 +101,7 @@ class RDoc::TopLevel < RDoc::Context
# Adds class or module +mod+. Used in the building phase # Adds class or module +mod+. Used in the building phase
# by the Ruby parser. # by the Ruby parser.
def add_to_classes_or_modules mod def add_to_classes_or_modules(mod)
@classes_or_modules << mod @classes_or_modules << mod
end end
@ -137,7 +128,7 @@ class RDoc::TopLevel < RDoc::Context
# TODO Why do we search through all classes/modules found, not just the # TODO Why do we search through all classes/modules found, not just the
# ones of this instance? # ones of this instance?
def find_class_or_module name def find_class_or_module(name)
@store.find_class_or_module name @store.find_class_or_module name
end end
@ -173,10 +164,8 @@ class RDoc::TopLevel < RDoc::Context
## ##
# URL for this with a +prefix+ # URL for this with a +prefix+
def http_url(prefix) def http_url
path = [prefix, @relative_name.tr('.', '_')] @relative_name.tr('.', '_') + '.html'
File.join(*path.compact) + '.html'
end end
def inspect # :nodoc: def inspect # :nodoc:
@ -188,13 +177,6 @@ class RDoc::TopLevel < RDoc::Context
] ]
end end
##
# Time this file was last modified, if known
def last_modified
@file_stat ? file_stat.mtime : nil
end
## ##
# Dumps this TopLevel for use by ri. See also #marshal_load # Dumps this TopLevel for use by ri. See also #marshal_load
@ -210,13 +192,11 @@ class RDoc::TopLevel < RDoc::Context
## ##
# Loads this TopLevel from +array+. # Loads this TopLevel from +array+.
def marshal_load array # :nodoc: def marshal_load(array) # :nodoc:
initialize array[1] initialize array[1]
@parser = array[2] @parser = array[2]
@comment = array[3] @comment = RDoc::Comment.from_document array[3]
@file_stat = nil
end end
## ##
@ -246,10 +226,12 @@ class RDoc::TopLevel < RDoc::Context
# Path to this file for use with HTML generator output. # Path to this file for use with HTML generator output.
def path def path
http_url @store.rdoc.generator.file_dir prefix = options.file_path_prefix
return http_url unless prefix
File.join(prefix, http_url)
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[#{self.class}: ", "]" do q.group 2, "[#{self.class}: ", "]" do
q.text "base name: #{base_name.inspect}" q.text "base name: #{base_name.inspect}"
q.breakable q.breakable

View file

@ -53,7 +53,7 @@ class RDoc::Comment
# Creates a new comment with +text+ that is found in the RDoc::TopLevel # Creates a new comment with +text+ that is found in the RDoc::TopLevel
# +location+. # +location+.
def initialize text = nil, location = nil, language = nil def initialize(text = nil, location = nil, language = nil)
@location = location @location = location
@text = text.nil? ? nil : text.dup @text = text.nil? ? nil : text.dup
@language = language @language = language
@ -67,11 +67,11 @@ class RDoc::Comment
#-- #--
# TODO deep copy @document # TODO deep copy @document
def initialize_copy copy # :nodoc: def initialize_copy(copy) # :nodoc:
@text = copy.text.dup @text = copy.text.dup
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class === other and self.class === other and
other.text == @text and other.location == @location other.text == @text and other.location == @location
end end
@ -92,7 +92,7 @@ class RDoc::Comment
# # ARGF.to_a(limit) -> array # # ARGF.to_a(limit) -> array
# # ARGF.to_a(sep, limit) -> array # # ARGF.to_a(sep, limit) -> array
def extract_call_seq method def extract_call_seq
# we must handle situations like the above followed by an unindented first # we must handle situations like the above followed by an unindented first
# comment. The difficulty is to make sure not to match lines starting # comment. The difficulty is to make sure not to match lines starting
# with ARGF at the same indent, but that are after the first description # with ARGF at the same indent, but that are after the first description
@ -116,23 +116,20 @@ class RDoc::Comment
@text.slice! all_start...all_stop @text.slice! all_start...all_stop
seq.gsub!(/^\s*/, '') seq.gsub!(/^\s*/, '')
method.call_seq = seq
end end
method
end end
## ##
# A comment is empty if its text String is empty. # A comment is empty if its text String is empty.
def empty? def empty?
@text.empty? @text.empty? && (@document.nil? || @document.empty?)
end end
## ##
# HACK dubious # HACK dubious
def encode! encoding def encode!(encoding)
@text = String.new @text, encoding: encoding @text = String.new @text, encoding: encoding
self self
end end
@ -140,7 +137,7 @@ class RDoc::Comment
## ##
# Sets the format of this comment and resets any parsed document # Sets the format of this comment and resets any parsed document
def format= format def format=(format)
@format = format @format = format
@document = nil @document = nil
end end
@ -211,7 +208,7 @@ class RDoc::Comment
# #
# An error is raised if the comment contains a document but no text. # An error is raised if the comment contains a document but no text.
def text= text def text=(text)
raise RDoc::Error, 'replacing document-only comment is not allowed' if raise RDoc::Error, 'replacing document-only comment is not allowed' if
@text.nil? and @document @text.nil? and @document
@ -226,4 +223,14 @@ class RDoc::Comment
@format == 'tomdoc' @format == 'tomdoc'
end end
##
# Create a new parsed comment from a document
def self.from_document(document) # :nodoc:
comment = RDoc::Comment.new('')
comment.document = document
comment.location = RDoc::TopLevel.new(document.file) if document.file
comment
end
end end

View file

@ -124,7 +124,7 @@ class RDoc::CrossReference
# Allows cross-references to be created based on the given +context+ # Allows cross-references to be created based on the given +context+
# (RDoc::Context). # (RDoc::Context).
def initialize context def initialize(context)
@context = context @context = context
@store = context.store @store = context.store
@ -134,7 +134,7 @@ class RDoc::CrossReference
## ##
# Returns a method reference to +name+. # Returns a method reference to +name+.
def resolve_method name def resolve_method(name)
ref = nil ref = nil
if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then
@ -187,7 +187,7 @@ class RDoc::CrossReference
# returned. If +name+ is escaped +name+ is returned. If +name+ is not # returned. If +name+ is escaped +name+ is returned. If +name+ is not
# found +text+ is returned. # found +text+ is returned.
def resolve name, text def resolve(name, text)
return @seen[name] if @seen.include? name return @seen[name] if @seen.include? name
ref = case name ref = case name

View file

@ -29,7 +29,7 @@ module RDoc::Encoding
# If +force_transcode+ is true the document will be transcoded and any # If +force_transcode+ is true the document will be transcoded and any
# unknown character in the target encoding will be replaced with '?' # unknown character in the target encoding will be replaced with '?'
def self.read_file filename, encoding, force_transcode = false def self.read_file(filename, encoding, force_transcode = false)
content = File.open filename, "rb" do |f| f.read end content = File.open filename, "rb" do |f| f.read end
content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/ content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/
@ -89,7 +89,7 @@ module RDoc::Encoding
## ##
# Detects the encoding of +string+ based on the magic comment # Detects the encoding of +string+ based on the magic comment
def self.detect_encoding string def self.detect_encoding(string)
result = HEADER_REGEXP.match string result = HEADER_REGEXP.match string
name = result && result[:name] name = result && result[:name]
@ -99,7 +99,7 @@ module RDoc::Encoding
## ##
# Removes magic comments and shebang # Removes magic comments and shebang
def self.remove_magic_comment string def self.remove_magic_comment(string)
string.sub HEADER_REGEXP do |s| string.sub HEADER_REGEXP do |s|
s.gsub(/[^\n]/, '') s.gsub(/[^\n]/, '')
end end
@ -109,7 +109,7 @@ module RDoc::Encoding
# Changes encoding based on +encoding+ without converting and returns new # Changes encoding based on +encoding+ without converting and returns new
# string # string
def self.change_encoding text, encoding def self.change_encoding(text, encoding)
if text.kind_of? RDoc::Comment if text.kind_of? RDoc::Comment
text.encode! encoding text.encode! encoding
else else

View file

@ -9,7 +9,7 @@ class RDoc::ERBPartial < ERB
# Overrides +compiler+ startup to set the +eoutvar+ to an empty string only # Overrides +compiler+ startup to set the +eoutvar+ to an empty string only
# if it isn't already set. # if it isn't already set.
def set_eoutvar compiler, eoutvar = '_erbout' def set_eoutvar(compiler, eoutvar = '_erbout')
super super
compiler.pre_cmd = ["#{eoutvar} ||= +''"] compiler.pre_cmd = ["#{eoutvar} ||= +''"]

View file

@ -20,14 +20,14 @@ class RDoc::ERBIO < ERB
## ##
# Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize # Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize
def initialize str, trim_mode: nil, eoutvar: 'io' def initialize(str, trim_mode: nil, eoutvar: 'io')
super(str, trim_mode: trim_mode, eoutvar: eoutvar) super(str, trim_mode: trim_mode, eoutvar: eoutvar)
end end
## ##
# Instructs +compiler+ how to write to +io_variable+ # Instructs +compiler+ how to write to +io_variable+
def set_eoutvar compiler, io_variable def set_eoutvar(compiler, io_variable)
compiler.put_cmd = "#{io_variable}.write" compiler.put_cmd = "#{io_variable}.write"
compiler.insert_cmd = "#{io_variable}.write" compiler.insert_cmd = "#{io_variable}.write"
compiler.pre_cmd = [] compiler.pre_cmd = []

View file

@ -73,12 +73,6 @@ class RDoc::Generator::Darkfish
css/rdoc.css css/rdoc.css
] ]
##
# Path to this file's parent directory. Used to find templates and other
# resources.
GENERATOR_DIR = File.join 'rdoc', 'generator'
## ##
# Release Version # Release Version
@ -156,7 +150,7 @@ class RDoc::Generator::Darkfish
## ##
# Initialize a few instance variables before we start # Initialize a few instance variables before we start
def initialize store, options def initialize(store, options)
@store = store @store = store
@options = options @options = options
@ -184,22 +178,6 @@ class RDoc::Generator::Darkfish
$stderr.puts(*msg) $stderr.puts(*msg)
end end
##
# Directory where generated class HTML files live relative to the output
# dir.
def class_dir
nil
end
##
# Directory where generated class HTML files live relative to the output
# dir.
def file_dir
nil
end
## ##
# Create the directories the generated docs will live in if they don't # Create the directories the generated docs will live in if they don't
# already exist. # already exist.
@ -291,7 +269,7 @@ class RDoc::Generator::Darkfish
# Return a list of the documented modules sorted by salience first, then # Return a list of the documented modules sorted by salience first, then
# by name. # by name.
def get_sorted_module_list classes def get_sorted_module_list(classes)
classes.select do |klass| classes.select do |klass|
klass.display? klass.display?
end.sort end.sort
@ -301,8 +279,6 @@ class RDoc::Generator::Darkfish
# Generate an index page which lists all the classes which are documented. # Generate an index page which lists all the classes which are documented.
def generate_index def generate_index
setup
template_file = @template_dir + 'index.rhtml' template_file = @template_dir + 'index.rhtml'
return unless template_file.exist? return unless template_file.exist?
@ -316,11 +292,14 @@ class RDoc::Generator::Darkfish
asset_rel_prefix = rel_prefix + @asset_rel_path asset_rel_prefix = rel_prefix + @asset_rel_path
@title = @options.title @title = @options.title
@main_page = @files.find { |f| f.full_name == @options.main_page }
render_template template_file, out_file do |io| render_template template_file, out_file do |io|
here = binding here = binding
# suppress 1.9.3 warning # suppress 1.9.3 warning
here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
# some partials rely on the presence of current variable to render
here.local_variable_set(:current, @main_page) if @main_page
here here
end end
rescue => e rescue => e
@ -334,9 +313,7 @@ class RDoc::Generator::Darkfish
## ##
# Generates a class file for +klass+ # Generates a class file for +klass+
def generate_class klass, template_file = nil def generate_class(klass, template_file = nil)
setup
current = klass current = klass
template_file ||= @template_dir + 'class.rhtml' template_file ||= @template_dir + 'class.rhtml'
@ -348,7 +325,9 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix += @asset_rel_path if @file_output search_index_rel_prefix += @asset_rel_path if @file_output
asset_rel_prefix = rel_prefix + @asset_rel_path asset_rel_prefix = rel_prefix + @asset_rel_path
svninfo = get_svninfo(current)
breadcrumb = # used in templates
breadcrumb = generate_nesting_namespaces_breadcrumb(current, rel_prefix)
@title = "#{klass.type} #{klass.full_name} - #{@options.title}" @title = "#{klass.type} #{klass.full_name} - #{@options.title}"
@ -357,7 +336,6 @@ class RDoc::Generator::Darkfish
here = binding here = binding
# suppress 1.9.3 warning # suppress 1.9.3 warning
here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
here.local_variable_set(:svninfo, svninfo)
here here
end end
end end
@ -366,8 +344,6 @@ class RDoc::Generator::Darkfish
# Generate a documentation file for each class and module # Generate a documentation file for each class and module
def generate_class_files def generate_class_files
setup
template_file = @template_dir + 'class.rhtml' template_file = @template_dir + 'class.rhtml'
template_file = @template_dir + 'classpage.rhtml' unless template_file = @template_dir + 'classpage.rhtml' unless
template_file.exist? template_file.exist?
@ -393,8 +369,6 @@ class RDoc::Generator::Darkfish
# Generate a documentation file for each file # Generate a documentation file for each file
def generate_file_files def generate_file_files
setup
page_file = @template_dir + 'page.rhtml' page_file = @template_dir + 'page.rhtml'
fileinfo_file = @template_dir + 'fileinfo.rhtml' fileinfo_file = @template_dir + 'fileinfo.rhtml'
@ -461,9 +435,7 @@ class RDoc::Generator::Darkfish
## ##
# Generate a page file for +file+ # Generate a page file for +file+
def generate_page file def generate_page(file)
setup
template_file = @template_dir + 'page.rhtml' template_file = @template_dir + 'page.rhtml'
out_file = @outputdir + file.path out_file = @outputdir + file.path
@ -490,9 +462,7 @@ class RDoc::Generator::Darkfish
## ##
# Generates the 404 page for the RDoc servlet # Generates the 404 page for the RDoc servlet
def generate_servlet_not_found message def generate_servlet_not_found(message)
setup
template_file = @template_dir + 'servlet_not_found.rhtml' template_file = @template_dir + 'servlet_not_found.rhtml'
return unless template_file.exist? return unless template_file.exist?
@ -523,9 +493,7 @@ class RDoc::Generator::Darkfish
## ##
# Generates the servlet root page for the RDoc servlet # Generates the servlet root page for the RDoc servlet
def generate_servlet_root installed def generate_servlet_root(installed)
setup
template_file = @template_dir + 'servlet_root.rhtml' template_file = @template_dir + 'servlet_root.rhtml'
return unless template_file.exist? return unless template_file.exist?
@ -551,8 +519,6 @@ class RDoc::Generator::Darkfish
# Generate an index page which lists all the classes which are documented. # Generate an index page which lists all the classes which are documented.
def generate_table_of_contents def generate_table_of_contents
setup
template_file = @template_dir + 'table_of_contents.rhtml' template_file = @template_dir + 'table_of_contents.rhtml'
return unless template_file.exist? return unless template_file.exist?
@ -581,7 +547,7 @@ class RDoc::Generator::Darkfish
raise error raise error
end end
def install_rdoc_static_file source, destination, options # :nodoc: def install_rdoc_static_file(source, destination, options) # :nodoc:
return unless source.exist? return unless source.exist?
begin begin
@ -614,65 +580,13 @@ class RDoc::Generator::Darkfish
@modsort = get_sorted_module_list @classes @modsort = get_sorted_module_list @classes
end end
##
# Return a string describing the amount of time in the given number of
# seconds in terms a human can understand easily.
def time_delta_string seconds
return 'less than a minute' if seconds < 60
return "#{seconds / 60} minute#{seconds / 60 == 1 ? '' : 's'}" if
seconds < 3000 # 50 minutes
return 'about one hour' if seconds < 5400 # 90 minutes
return "#{seconds / 3600} hours" if seconds < 64800 # 18 hours
return 'one day' if seconds < 86400 # 1 day
return 'about one day' if seconds < 172800 # 2 days
return "#{seconds / 86400} days" if seconds < 604800 # 1 week
return 'about one week' if seconds < 1209600 # 2 week
return "#{seconds / 604800} weeks" if seconds < 7257600 # 3 months
return "#{seconds / 2419200} months" if seconds < 31536000 # 1 year
return "#{seconds / 31536000} years"
end
# %q$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $"
SVNID_PATTERN = /
\$Id:\s
(\S+)\s # filename
(\d+)\s # rev
(\d{4}-\d{2}-\d{2})\s # Date (YYYY-MM-DD)
(\d{2}:\d{2}:\d{2}Z)\s # Time (HH:MM:SSZ)
(\w+)\s # committer
\$$
/x
##
# Try to extract Subversion information out of the first constant whose
# value looks like a subversion Id tag. If no matching constant is found,
# and empty hash is returned.
def get_svninfo klass
constants = klass.constants or return {}
constants.find { |c| c.value =~ SVNID_PATTERN } or return {}
filename, rev, date, time, committer = $~.captures
commitdate = Time.parse "#{date} #{time}"
return {
:filename => filename,
:rev => Integer(rev),
:commitdate => commitdate,
:commitdelta => time_delta_string(Time.now - commitdate),
:committer => committer,
}
end
## ##
# Creates a template from its components and the +body_file+. # Creates a template from its components and the +body_file+.
# #
# For backwards compatibility, if +body_file+ contains "<html" the body is # For backwards compatibility, if +body_file+ contains "<html" the body is
# used directly. # used directly.
def assemble_template body_file def assemble_template(body_file)
body = body_file.read body = body_file.read
return body if body =~ /<html/ return body if body =~ /<html/
@ -681,7 +595,7 @@ class RDoc::Generator::Darkfish
<<-TEMPLATE <<-TEMPLATE
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="#{@options.locale&.name || 'en'}">
<head> <head>
#{head_file.read} #{head_file.read}
@ -693,7 +607,7 @@ class RDoc::Generator::Darkfish
# Renders the ERb contained in +file_name+ relative to the template # Renders the ERb contained in +file_name+ relative to the template
# directory and returns the result based on the current context. # directory and returns the result based on the current context.
def render file_name def render(file_name)
template_file = @template_dir + file_name template_file = @template_dir + file_name
template = template_for template_file, false, RDoc::ERBPartial template = template_for template_file, false, RDoc::ERBPartial
@ -711,7 +625,7 @@ class RDoc::Generator::Darkfish
# #
# An io will be yielded which must be captured by binding in the caller. # An io will be yielded which must be captured by binding in the caller.
def render_template template_file, out_file = nil # :yield: io def render_template(template_file, out_file = nil) # :yield: io
io_output = out_file && !@dry_run && @file_output io_output = out_file && !@dry_run && @file_output
erb_klass = io_output ? RDoc::ERBIO : ERB erb_klass = io_output ? RDoc::ERBIO : ERB
@ -745,7 +659,7 @@ class RDoc::Generator::Darkfish
# Creates the result for +template+ with +context+. If an error is raised a # Creates the result for +template+ with +context+. If an error is raised a
# Pathname +template_file+ will indicate the file where the error occurred. # Pathname +template_file+ will indicate the file where the error occurred.
def template_result template, context, template_file def template_result(template, context, template_file)
template.filename = template_file.to_s template.filename = template_file.to_s
template.result context template.result context
rescue NoMethodError => e rescue NoMethodError => e
@ -758,7 +672,7 @@ class RDoc::Generator::Darkfish
## ##
# Retrieves a cache template for +file+, if present, or fills the cache. # Retrieves a cache template for +file+, if present, or fills the cache.
def template_for file, page = true, klass = ERB def template_for(file, page = true, klass = ERB)
template = @template_cache[file] template = @template_cache[file]
return template if template return template if template
@ -780,32 +694,39 @@ class RDoc::Generator::Darkfish
template template
end end
# Returns an excerpt of the content for usage in meta description tags # :stopdoc:
def excerpt(content) ParagraphExcerptRegexpOther = %r[\b\w[^./:]++\.]
text = case content # use \p/\P{letter} instead of \w/\W in Unicode
ParagraphExcerptRegexpUnicode = %r[\b\p{letter}[^./:]++\.]
# :startdoc:
# Returns an excerpt of the comment for usage in meta description tags
def excerpt(comment)
text = case comment
when RDoc::Comment when RDoc::Comment
content.text comment.text
when RDoc::Markup::Document
# This case is for page files that are not markdown nor rdoc
# We convert them to markdown for now as it's easier to extract the text
formatter = RDoc::Markup::ToMarkdown.new
formatter.start_accepting
formatter.accept_document(content)
formatter.end_accepting
else else
content comment
end end
# Match from a capital letter to the first period, discarding any links, so # Match from a capital letter to the first period, discarding any links, so
# that we don't end up matching badges in the README # that we don't end up matching badges in the README
first_paragraph_match = text.match(/[A-Z][^\.:\/]+\./) pattern = ParagraphExcerptRegexpUnicode
return text[0...150].gsub(/\n/, " ").squeeze(" ") unless first_paragraph_match begin
first_paragraph_match = text.match(pattern)
rescue Encoding::CompatibilityError
# The doc is non-ASCII text and encoded in other than Unicode base encodings.
raise if pattern == ParagraphExcerptRegexpOther
pattern = ParagraphExcerptRegexpOther
retry
end
return text[0...150].tr_s("\n", " ").squeeze(" ") unless first_paragraph_match
extracted_text = first_paragraph_match[0] extracted_text = first_paragraph_match[0]
second_paragraph = first_paragraph_match.post_match.match(/[A-Z][^\.:\/]+\./) second_paragraph = text.match(pattern, first_paragraph_match.end(0))
extracted_text << " " << second_paragraph[0] if second_paragraph extracted_text << " " << second_paragraph[0] if second_paragraph
extracted_text[0...150].gsub(/\n/, " ").squeeze(" ") extracted_text[0...150].tr_s("\n", " ").squeeze(" ")
end end
def generate_ancestor_list(ancestors, klass) def generate_ancestor_list(ancestors, klass)
@ -825,4 +746,67 @@ class RDoc::Generator::Darkfish
content << '</li></ul>' content << '</li></ul>'
end end
def generate_class_link(klass, rel_prefix)
if klass.display?
%(<code><a href="#{rel_prefix}/#{klass.path}">#{klass.name}</a></code>)
else
%(<code>#{klass.name}</code>)
end
end
def generate_class_index_content(classes, rel_prefix)
grouped_classes = group_classes_by_namespace_for_sidebar(classes)
return '' unless top = grouped_classes[nil]
solo = top.one? { |klass| klass.display? }
traverse_classes(top, grouped_classes, rel_prefix, solo)
end
def traverse_classes(klasses, grouped_classes, rel_prefix, solo = false)
content = +'<ul class="link-list">'
klasses.each do |index_klass|
if children = grouped_classes[index_klass.full_name]
content << %(<li><details#{solo ? ' open' : ''}><summary>#{generate_class_link(index_klass, rel_prefix)}</summary>)
content << traverse_classes(children, grouped_classes, rel_prefix)
content << '</details></li>'
solo = false
elsif index_klass.display?
content << %(<li>#{generate_class_link(index_klass, rel_prefix)}</li>)
end
end
"#{content}</ul>"
end
def group_classes_by_namespace_for_sidebar(classes)
grouped_classes = classes.group_by do |klass|
klass.full_name[/\A[^:]++(?:::[^:]++(?=::))*+(?=::[^:]*+\z)/]
end.select do |_, klasses|
klasses.any?(&:display?)
end
grouped_classes.values.each(&:uniq!)
grouped_classes
end
private
def nesting_namespaces_to_class_modules(klass)
tree = {}
klass.nesting_namespaces.zip(klass.fully_qualified_nesting_namespaces) do |ns, fqns|
tree[ns] = @store.classes_hash[fqns] || @store.modules_hash[fqns]
end
tree
end
def generate_nesting_namespaces_breadcrumb(klass, rel_prefix)
nesting_namespaces_to_class_modules(klass).map do |namespace, class_module|
path = class_module ? (rel_prefix + class_module.path).to_s : ""
{ name: namespace, path: path, self: klass.full_name == class_module&.full_name }
end
end
end end

View file

@ -86,12 +86,10 @@ class RDoc::Generator::JsonIndex
attr_reader :index # :nodoc: attr_reader :index # :nodoc:
## ##
# Creates a new generator. +parent_generator+ is used to determine the # Creates a new generator.
# class_dir and file_dir of links in the output index.
#
# +options+ are the same options passed to the parent generator. # +options+ are the same options passed to the parent generator.
def initialize parent_generator, options def initialize(parent_generator, options)
@parent_generator = parent_generator @parent_generator = parent_generator
@store = parent_generator.store @store = parent_generator.store
@options = options @options = options
@ -265,21 +263,7 @@ class RDoc::Generator::JsonIndex
end end
end end
## def reset(files, classes) # :nodoc:
# The directory classes are written to
def class_dir
@parent_generator.class_dir
end
##
# The directory files are written to
def file_dir
@parent_generator.file_dir
end
def reset files, classes # :nodoc:
@files = files @files = files
@classes = classes @classes = classes
@ -293,7 +277,7 @@ class RDoc::Generator::JsonIndex
## ##
# Removes whitespace and downcases +string+ # Removes whitespace and downcases +string+
def search_string string def search_string(string)
string.downcase.gsub(/\s/, '') string.downcase.gsub(/\s/, '')
end end

View file

@ -34,7 +34,7 @@ module RDoc::Generator::Markup
def formatter def formatter
return @formatter if defined? @formatter return @formatter if defined? @formatter
options = @store.rdoc.options options = @store.options
this = RDoc::Context === self ? self : @parent this = RDoc::Context === self ? self : @parent
@formatter = RDoc::Markup::ToHtmlCrossref.new options, this.path, this @formatter = RDoc::Markup::ToHtmlCrossref.new options, this.path, this
@ -55,6 +55,18 @@ module RDoc::Generator::Markup
end end
end end
##
# The preferred URL for this object.
def canonical_url
options = @store.options
if path
File.join(options.canonical_root, path.to_s)
else
options.canonical_root
end
end
end end
class RDoc::CodeObject class RDoc::CodeObject
@ -147,7 +159,7 @@ class RDoc::TopLevel
# command line option to set. # command line option to set.
def cvs_url def cvs_url
url = @store.rdoc.options.webcvs url = @store.options.webcvs
if /%s/ =~ url then if /%s/ =~ url then
url % @relative_name url % @relative_name

View file

@ -65,7 +65,7 @@ class RDoc::Generator::POT
## ##
# Set up a new .pot generator # Set up a new .pot generator
def initialize store, options #:not-new: def initialize(store, options) #:not-new:
@options = options @options = options
@store = store @store = store
end end
@ -81,11 +81,6 @@ class RDoc::Generator::POT
end end
end end
# :nodoc:
def class_dir
nil
end
private private
def extract_messages def extract_messages
extractor = MessageExtractor.new(@store) extractor = MessageExtractor.new(@store)

View file

@ -7,7 +7,7 @@ class RDoc::Generator::POT::MessageExtractor
## ##
# Creates a message extractor for +store+. # Creates a message extractor for +store+.
def initialize store def initialize(store)
@store = store @store = store
@po = RDoc::Generator::POT::PO.new @po = RDoc::Generator::POT::PO.new
end end
@ -25,7 +25,7 @@ class RDoc::Generator::POT::MessageExtractor
private private
def extract_from_klass klass def extract_from_klass(klass)
extract_text(klass.comment_location, klass.full_name) extract_text(klass.comment_location, klass.full_name)
klass.each_section do |section, constants, attributes| klass.each_section do |section, constants, attributes|
@ -35,11 +35,11 @@ class RDoc::Generator::POT::MessageExtractor
end end
end end
klass.each_constant do |constant| klass.constants.each do |constant|
extract_text(constant.comment, constant.full_name) extract_text(constant.comment, constant.full_name)
end end
klass.each_attribute do |attribute| klass.attributes.each do |attribute|
extract_text(attribute.comment, attribute.full_name) extract_text(attribute.comment, attribute.full_name)
end end
@ -48,7 +48,7 @@ class RDoc::Generator::POT::MessageExtractor
end end
end end
def extract_text text, comment, location = nil def extract_text(text, comment, location = nil)
return if text.nil? return if text.nil?
options = { options = {
@ -61,7 +61,7 @@ class RDoc::Generator::POT::MessageExtractor
end end
end end
def entry msgid, options def entry(msgid, options)
RDoc::Generator::POT::POEntry.new(msgid, options) RDoc::Generator::POT::POEntry.new(msgid, options)
end end

View file

@ -15,7 +15,7 @@ class RDoc::Generator::POT::PO
## ##
# Adds a PO entry to the PO. # Adds a PO entry to the PO.
def add entry def add(entry)
existing_entry = @entries[entry.msgid] existing_entry = @entries[entry.msgid]
if existing_entry if existing_entry
entry = existing_entry.merge(entry) entry = existing_entry.merge(entry)

View file

@ -26,7 +26,7 @@ class RDoc::Generator::POT::POEntry
# Creates a PO entry for +msgid+. Other values can be specified by # Creates a PO entry for +msgid+. Other values can be specified by
# +options+. # +options+.
def initialize msgid, options = {} def initialize(msgid, options = {})
@msgid = msgid @msgid = msgid
@msgstr = options[:msgstr] || "" @msgstr = options[:msgstr] || ""
@translator_comment = options[:translator_comment] @translator_comment = options[:translator_comment]
@ -53,7 +53,7 @@ msgstr #{format_message(@msgstr)}
## ##
# Merges the PO entry with +other_entry+. # Merges the PO entry with +other_entry+.
def merge other_entry def merge(other_entry)
options = { options = {
:extracted_comment => merge_string(@extracted_comment, :extracted_comment => merge_string(@extracted_comment,
other_entry.extracted_comment), other_entry.extracted_comment),
@ -69,7 +69,7 @@ msgstr #{format_message(@msgstr)}
private private
def format_comment mark, comment def format_comment(mark, comment)
return '' unless comment return '' unless comment
return '' if comment.empty? return '' if comment.empty?
@ -106,7 +106,7 @@ msgstr #{format_message(@msgstr)}
"\#, #{formatted_flags}\n" "\#, #{formatted_flags}\n"
end end
def format_message message def format_message(message)
return "\"#{escape(message)}\"" unless message.include?("\n") return "\"#{escape(message)}\"" unless message.include?("\n")
formatted_message = '""' formatted_message = '""'
@ -117,7 +117,7 @@ msgstr #{format_message(@msgstr)}
formatted_message formatted_message
end end
def escape string def escape(string)
string.gsub(/["\\\t\n]/) do |special_character| string.gsub(/["\\\t\n]/) do |special_character|
case special_character case special_character
when "\t" when "\t"
@ -130,11 +130,11 @@ msgstr #{format_message(@msgstr)}
end end
end end
def merge_string string1, string2 def merge_string(string1, string2)
[string1, string2].compact.join("\n") [string1, string2].compact.join("\n")
end end
def merge_array array1, array2 def merge_array(array1, array2)
(array1 + array2).uniq (array1 + array2).uniq
end end

View file

@ -14,7 +14,7 @@ class RDoc::Generator::RI
## ##
# Set up a new ri generator # Set up a new ri generator
def initialize store, options #:not-new: def initialize(store, options) #:not-new:
@options = options @options = options
@store = store @store = store
@store.path = '.' @store.path = '.'

View file

@ -25,6 +25,11 @@
<%- end -%> <%- end -%>
<%- end -%> <%- end -%>
<%- if canonical_url = @options.canonical_root -%>
<% canonical_url = current.canonical_url if defined?(current) %>
<link rel="canonical" href="<%= canonical_url %>">
<%- end -%>
<script type="text/javascript"> <script type="text/javascript">
var rdoc_rel_prefix = "<%= h asset_rel_prefix %>/"; var rdoc_rel_prefix = "<%= h asset_rel_prefix %>/";
var index_rel_prefix = "<%= h rel_prefix %>/"; var index_rel_prefix = "<%= h rel_prefix %>/";

View file

@ -1,19 +0,0 @@
<%- if !svninfo.empty? then %>
<div id="file-svninfo-section" class="nav-section">
<h3>VCS Info</h3>
<div class="section-body">
<dl class="svninfo">
<dt>Rev
<dd><%= svninfo[:rev] %>
<dt>Last Checked In
<dd><%= svninfo[:commitdate].strftime('%Y-%m-%d %H:%M:%S') %>
(<%= svninfo[:commitdelta] %> ago)
<dt>Checked in by
<dd><%= svninfo[:committer] %>
</dl>
</div>
</div>
<%- end -%>

View file

@ -1,34 +1,5 @@
<div id="classindex-section" class="nav-section"> <div id="classindex-section" class="nav-section">
<h3>Class and Module Index</h3> <h3>Class and Module Index</h3>
<%- <%= generate_class_index_content(@classes, rel_prefix) %>
all_classes = @classes.group_by do |klass|
klass.full_name[/\A[^:]++(?:::[^:]++(?=::))*+(?=::[^:]*+\z)/]
end.delete_if do |_, klasses|
!klasses.any?(&:display?)
end
link = proc do |index_klass, display = index_klass.display?|
if display
-%><code><a href="<%= rel_prefix %>/<%= index_klass.path %>"><%= index_klass.name %></a></code><%-
else
-%><code><%= index_klass.name %></code><%-
end
end
if top = all_classes[nil]
solo = top.one? {|klass| klass.display?}
traverse = proc do |klasses| -%>
<ul class="link-list">
<%- klasses.uniq!(&:full_name) -%>
<%- klasses.each do |index_klass| -%>
<%- if children = all_classes[index_klass.full_name] -%>
<li><details<% if solo; solo = false %> open<% end %>><summary><% link.call(index_klass) %></summary>
<%- traverse.call(children) -%>
</ul></details>
<%- elsif index_klass.display? -%>
<li><% link.call(index_klass, true) %>
<%- end -%>
<%- end -%>
<%- end -%>
<%- traverse.call(top) -%>
<%- end -%>
</div> </div>

View file

@ -3,7 +3,7 @@
<h3>Extended With Modules</h3> <h3>Extended With Modules</h3>
<ul class="link-list"> <ul class="link-list">
<%- klass.each_extend do |ext| -%> <%- klass.extends.each do |ext| -%>
<%- unless String === ext.module then -%> <%- unless String === ext.module then -%>
<li><a class="extend" href="<%= klass.aref_to ext.module.path %>"><%= ext.module.full_name %></a> <li><a class="extend" href="<%= klass.aref_to ext.module.path %>"><%= ext.module.full_name %></a>
<%- else -%> <%- else -%>

View file

@ -1,9 +0,0 @@
<div id="file-list-section" class="nav-section">
<h3>Defined In</h3>
<ul>
<%- klass.in_files.each do |tl| -%>
<li><%= h tl.relative_name %>
<%- end -%>
</ul>
</div>

View file

@ -3,7 +3,7 @@
<h3>Included Modules</h3> <h3>Included Modules</h3>
<ul class="link-list"> <ul class="link-list">
<%- klass.each_include do |inc| -%> <%- klass.includes.each do |inc| -%>
<%- unless String === inc.module then -%> <%- unless String === inc.module then -%>
<li><a class="include" href="<%= klass.aref_to inc.module.path %>"><%= inc.module.full_name %></a> <li><a class="include" href="<%= klass.aref_to inc.module.path %>"><%= inc.module.full_name %></a>
<%- else -%> <%- else -%>

View file

@ -18,6 +18,21 @@
</nav> </nav>
<main role="main" aria-labelledby="<%=h klass.aref %>"> <main role="main" aria-labelledby="<%=h klass.aref %>">
<%# If nesting level is 1, breadcrumb list is not needed %>
<% if breadcrumb.size > 1 %>
<ol role="navigation" aria-label="breadcrumb" class="breadcrumb">
<% breadcrumb.each do |namespace| %>
<li>
<% if namespace[:self] %>
<span><%= namespace[:name] %></span>
<% else %>
<a href="<%= namespace[:path] %>"><%= namespace[:name] %></a><span>::</span>
<% end %>
</li>
<% end %>
</ol>
<% end %>
<h1 id="<%=h klass.aref %>" class="anchor-link <%= klass.type %>"> <h1 id="<%=h klass.aref %>" class="anchor-link <%= klass.type %>">
<%= klass.type %> <%= klass.full_name %> <%= klass.type %> <%= klass.full_name %>
</h1> </h1>

View file

@ -96,6 +96,8 @@ main .anchor-link:target {
a { a {
color: var(--link-color); color: var(--link-color);
transition: color 0.3s ease; transition: color 0.3s ease;
text-decoration: underline;
text-underline-offset: 0.2em; /* Make sure it doesn't overlap with underscores in a method name. */
} }
a:hover { a:hover {
@ -199,6 +201,19 @@ nav h3,
font-size: 1em; font-size: 1em;
} }
ol.breadcrumb {
display: flex;
padding: 0;
margin: 0 0 1em;
}
ol.breadcrumb li {
display: block;
list-style: none;
font-size: 125%;
}
nav ul, nav ul,
nav dl, nav dl,
nav p { nav p {

View file

@ -7,6 +7,7 @@
<%= render '_sidebar_search.rhtml' %> <%= render '_sidebar_search.rhtml' %>
</div> </div>
<%= render '_sidebar_table_of_contents.rhtml' if defined?(current) %>
<%= render '_sidebar_pages.rhtml' %> <%= render '_sidebar_pages.rhtml' %>
<%= render '_sidebar_classes.rhtml' %> <%= render '_sidebar_classes.rhtml' %>
@ -14,10 +15,9 @@
</nav> </nav>
<main role="main"> <main role="main">
<%- if @options.main_page and <%- if @main_page %>
main_page = @files.find { |f| f.full_name == @options.main_page } then %> <%= @main_page.description %>
<%= main_page.description %>
<%- else -%> <%- else -%>
<p>This is the API documentation for <%= h @title %>. <p>This is the API documentation for <%= h @title %>.
<%- end -%> <%- end -%>
</main> </main>

View file

@ -10978,7 +10978,7 @@ class RDoc::Markdown
return _tmp return _tmp
end end
# Image = "!" (ExplicitLink | ReferenceLink):a { "rdoc-image:#{a[/\[(.*)\]/, 1]}" } # Image = "!" ExplicitLinkWithLabel:a { "rdoc-image:#{a[:link]}:#{a[:label]}" }
def _Image def _Image
_save = self.pos _save = self.pos
@ -10988,24 +10988,13 @@ class RDoc::Markdown
self.pos = _save self.pos = _save
break break
end end
_tmp = apply(:_ExplicitLinkWithLabel)
_save1 = self.pos
while true # choice
_tmp = apply(:_ExplicitLink)
break if _tmp
self.pos = _save1
_tmp = apply(:_ReferenceLink)
break if _tmp
self.pos = _save1
break
end # end choice
a = @result a = @result
unless _tmp unless _tmp
self.pos = _save self.pos = _save
break break
end end
@result = begin; "rdoc-image:#{a[/\[(.*)\]/, 1]}" ; end @result = begin; "rdoc-image:#{a[:link]}:#{a[:label]}" ; end
_tmp = true _tmp = true
unless _tmp unless _tmp
self.pos = _save self.pos = _save
@ -11153,13 +11142,36 @@ class RDoc::Markdown
return _tmp return _tmp
end end
# ExplicitLink = Label:l "(" @Sp Source:s Spnl Title @Sp ")" { "{#{l}}[#{s}]" } # ExplicitLink = ExplicitLinkWithLabel:a { "{#{a[:label]}}[#{a[:link]}]" }
def _ExplicitLink def _ExplicitLink
_save = self.pos
while true # sequence
_tmp = apply(:_ExplicitLinkWithLabel)
a = @result
unless _tmp
self.pos = _save
break
end
@result = begin; "{#{a[:label]}}[#{a[:link]}]" ; end
_tmp = true
unless _tmp
self.pos = _save
end
break
end # end sequence
set_failed_rule :_ExplicitLink unless _tmp
return _tmp
end
# ExplicitLinkWithLabel = Label:label "(" @Sp Source:link Spnl Title @Sp ")" { { label: label, link: link } }
def _ExplicitLinkWithLabel
_save = self.pos _save = self.pos
while true # sequence while true # sequence
_tmp = apply(:_Label) _tmp = apply(:_Label)
l = @result label = @result
unless _tmp unless _tmp
self.pos = _save self.pos = _save
break break
@ -11175,7 +11187,7 @@ class RDoc::Markdown
break break
end end
_tmp = apply(:_Source) _tmp = apply(:_Source)
s = @result link = @result
unless _tmp unless _tmp
self.pos = _save self.pos = _save
break break
@ -11200,7 +11212,7 @@ class RDoc::Markdown
self.pos = _save self.pos = _save
break break
end end
@result = begin; "{#{l}}[#{s}]" ; end @result = begin; { label: label, link: link } ; end
_tmp = true _tmp = true
unless _tmp unless _tmp
self.pos = _save self.pos = _save
@ -11208,7 +11220,7 @@ class RDoc::Markdown
break break
end # end sequence end # end sequence
set_failed_rule :_ExplicitLink unless _tmp set_failed_rule :_ExplicitLinkWithLabel unless _tmp
return _tmp return _tmp
end end
@ -16711,12 +16723,13 @@ class RDoc::Markdown
Rules[:_StrongStar] = rule_info("StrongStar", "\"**\" !@Whitespace @StartList:a (!\"**\" Inline:b { a << b })+ \"**\" { strong a.join }") Rules[:_StrongStar] = rule_info("StrongStar", "\"**\" !@Whitespace @StartList:a (!\"**\" Inline:b { a << b })+ \"**\" { strong a.join }")
Rules[:_StrongUl] = rule_info("StrongUl", "\"__\" !@Whitespace @StartList:a (!\"__\" Inline:b { a << b })+ \"__\" { strong a.join }") Rules[:_StrongUl] = rule_info("StrongUl", "\"__\" !@Whitespace @StartList:a (!\"__\" Inline:b { a << b })+ \"__\" { strong a.join }")
Rules[:_Strike] = rule_info("Strike", "&{ strike? } \"~~\" !@Whitespace @StartList:a (!\"~~\" Inline:b { a << b })+ \"~~\" { strike a.join }") Rules[:_Strike] = rule_info("Strike", "&{ strike? } \"~~\" !@Whitespace @StartList:a (!\"~~\" Inline:b { a << b })+ \"~~\" { strike a.join }")
Rules[:_Image] = rule_info("Image", "\"!\" (ExplicitLink | ReferenceLink):a { \"rdoc-image:\#{a[/\\[(.*)\\]/, 1]}\" }") Rules[:_Image] = rule_info("Image", "\"!\" ExplicitLinkWithLabel:a { \"rdoc-image:\#{a[:link]}:\#{a[:label]}\" }")
Rules[:_Link] = rule_info("Link", "(ExplicitLink | ReferenceLink | AutoLink)") Rules[:_Link] = rule_info("Link", "(ExplicitLink | ReferenceLink | AutoLink)")
Rules[:_ReferenceLink] = rule_info("ReferenceLink", "(ReferenceLinkDouble | ReferenceLinkSingle)") Rules[:_ReferenceLink] = rule_info("ReferenceLink", "(ReferenceLinkDouble | ReferenceLinkSingle)")
Rules[:_ReferenceLinkDouble] = rule_info("ReferenceLinkDouble", "Label:content < Spnl > !\"[]\" Label:label { link_to content, label, text }") Rules[:_ReferenceLinkDouble] = rule_info("ReferenceLinkDouble", "Label:content < Spnl > !\"[]\" Label:label { link_to content, label, text }")
Rules[:_ReferenceLinkSingle] = rule_info("ReferenceLinkSingle", "Label:content < (Spnl \"[]\")? > { link_to content, content, text }") Rules[:_ReferenceLinkSingle] = rule_info("ReferenceLinkSingle", "Label:content < (Spnl \"[]\")? > { link_to content, content, text }")
Rules[:_ExplicitLink] = rule_info("ExplicitLink", "Label:l \"(\" @Sp Source:s Spnl Title @Sp \")\" { \"{\#{l}}[\#{s}]\" }") Rules[:_ExplicitLink] = rule_info("ExplicitLink", "ExplicitLinkWithLabel:a { \"{\#{a[:label]}}[\#{a[:link]}]\" }")
Rules[:_ExplicitLinkWithLabel] = rule_info("ExplicitLinkWithLabel", "Label:label \"(\" @Sp Source:link Spnl Title @Sp \")\" { { label: label, link: link } }")
Rules[:_Source] = rule_info("Source", "(\"<\" < SourceContents > \">\" | < SourceContents >) { text }") Rules[:_Source] = rule_info("Source", "(\"<\" < SourceContents > \">\" | < SourceContents >) { text }")
Rules[:_SourceContents] = rule_info("SourceContents", "((!\"(\" !\")\" !\">\" Nonspacechar)+ | \"(\" SourceContents \")\")*") Rules[:_SourceContents] = rule_info("SourceContents", "((!\"(\" !\")\" !\">\" Nonspacechar)+ | \"(\" SourceContents \")\")*")
Rules[:_Title] = rule_info("Title", "(TitleSingle | TitleDouble | \"\"):a { a }") Rules[:_Title] = rule_info("Title", "(TitleSingle | TitleDouble | \"\"):a { a }")

View file

@ -0,0 +1 @@
*.rb

View file

@ -118,7 +118,7 @@ class RDoc::Markup
## ##
# Parses +str+ into an RDoc::Markup::Document. # Parses +str+ into an RDoc::Markup::Document.
def self.parse str def self.parse(str)
RDoc::Markup::Parser.parse str RDoc::Markup::Parser.parse str
rescue RDoc::Markup::Parser::Error => e rescue RDoc::Markup::Parser::Error => e
$stderr.puts <<-EOF $stderr.puts <<-EOF
@ -148,7 +148,7 @@ https://github.com/ruby/rdoc/issues
# structure (paragraphs, lists, and so on). Invoke an event handler as we # structure (paragraphs, lists, and so on). Invoke an event handler as we
# identify significant chunks. # identify significant chunks.
def initialize attribute_manager = nil def initialize(attribute_manager = nil)
@attribute_manager = attribute_manager || RDoc::Markup::AttributeManager.new @attribute_manager = attribute_manager || RDoc::Markup::AttributeManager.new
@output = nil @output = nil
end end
@ -185,7 +185,7 @@ https://github.com/ruby/rdoc/issues
# We take +input+, parse it if necessary, then invoke the output +formatter+ # We take +input+, parse it if necessary, then invoke the output +formatter+
# using a Visitor to render the result. # using a Visitor to render the result.
def convert input, formatter def convert(input, formatter)
document = case input document = case input
when RDoc::Markup::Document then when RDoc::Markup::Document then
input input

View file

@ -107,7 +107,7 @@ class RDoc::Markup::AttributeManager
## ##
# Changes the current attribute from +current+ to +new+ # Changes the current attribute from +current+ to +new+
def change_attribute current, new def change_attribute(current, new)
diff = current ^ new diff = current ^ new
attribute(new & diff, current & diff) attribute(new & diff, current & diff)
end end
@ -116,7 +116,7 @@ class RDoc::Markup::AttributeManager
# Used by the tests to change attributes by name from +current_set+ to # Used by the tests to change attributes by name from +current_set+ to
# +new_set+ # +new_set+
def changed_attribute_by_name current_set, new_set def changed_attribute_by_name(current_set, new_set)
current = new = 0 current = new = 0
current_set.each do |name| current_set.each do |name|
current |= @attributes.bitmap_for(name) current |= @attributes.bitmap_for(name)
@ -220,7 +220,7 @@ class RDoc::Markup::AttributeManager
## ##
# Converts regexp handling sequences to RDoc attributes # Converts regexp handling sequences to RDoc attributes
def convert_regexp_handlings str, attrs, exclusive = false def convert_regexp_handlings(str, attrs, exclusive = false)
@regexp_handlings.each do |regexp, attribute| @regexp_handlings.each do |regexp, attribute|
next unless exclusive == exclusive?(attribute) next unless exclusive == exclusive?(attribute)
str.scan(regexp) do str.scan(regexp) do
@ -295,7 +295,7 @@ class RDoc::Markup::AttributeManager
# #
# @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK) # @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK)
def add_regexp_handling pattern, name, exclusive = false def add_regexp_handling(pattern, name, exclusive = false)
bitmap = @attributes.bitmap_for(name) bitmap = @attributes.bitmap_for(name)
@regexp_handlings << [pattern, bitmap] @regexp_handlings << [pattern, bitmap]
@exclusive_bitmap |= bitmap if exclusive @exclusive_bitmap |= bitmap if exclusive
@ -304,7 +304,7 @@ class RDoc::Markup::AttributeManager
## ##
# Processes +str+ converting attributes, HTML and regexp handlings # Processes +str+ converting attributes, HTML and regexp handlings
def flow str def flow(str)
@str = str.dup @str = str.dup
mask_protected_sequences mask_protected_sequences

View file

@ -26,7 +26,7 @@ class RDoc::Markup::Attributes
## ##
# Returns a unique bit for +name+ # Returns a unique bit for +name+
def bitmap_for name def bitmap_for(name)
bitmap = @name_to_bitmap.assoc name bitmap = @name_to_bitmap.assoc name
unless bitmap then unless bitmap then
@ -43,7 +43,7 @@ class RDoc::Markup::Attributes
## ##
# Returns a string representation of +bitmap+ # Returns a string representation of +bitmap+
def as_string bitmap def as_string(bitmap)
return 'none' if bitmap.zero? return 'none' if bitmap.zero?
res = [] res = []
@ -57,7 +57,7 @@ class RDoc::Markup::Attributes
## ##
# yields each attribute name in +bitmap+ # yields each attribute name in +bitmap+
def each_name_of bitmap def each_name_of(bitmap)
return enum_for __method__, bitmap unless block_given? return enum_for __method__, bitmap unless block_given?
@name_to_bitmap.each do |name, bit| @name_to_bitmap.each do |name, bit|

View file

@ -16,11 +16,11 @@ class RDoc::Markup::BlankLine
## ##
# Calls #accept_blank_line on +visitor+ # Calls #accept_blank_line on +visitor+
def accept visitor def accept(visitor)
visitor.accept_blank_line self visitor.accept_blank_line self
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.text 'blankline' q.text 'blankline'
end end

View file

@ -7,7 +7,7 @@ class RDoc::Markup::BlockQuote < RDoc::Markup::Raw
## ##
# Calls #accept_block_quote on +visitor+ # Calls #accept_block_quote on +visitor+
def accept visitor def accept(visitor)
visitor.accept_block_quote self visitor.accept_block_quote self
end end

View file

@ -37,7 +37,7 @@ class RDoc::Markup::Document
## ##
# Appends +part+ to the document # Appends +part+ to the document
def << part def <<(part)
case part case part
when RDoc::Markup::Document then when RDoc::Markup::Document then
unless part.empty? then unless part.empty? then
@ -53,7 +53,7 @@ class RDoc::Markup::Document
end end
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class == other.class and self.class == other.class and
@file == other.file and @file == other.file and
@parts == other.parts @parts == other.parts
@ -62,7 +62,7 @@ class RDoc::Markup::Document
## ##
# Runs this document and all its #items through +visitor+ # Runs this document and all its #items through +visitor+
def accept visitor def accept(visitor)
visitor.start_accepting visitor.start_accepting
visitor.accept_document self visitor.accept_document self
@ -73,14 +73,14 @@ class RDoc::Markup::Document
## ##
# Concatenates the given +parts+ onto the document # Concatenates the given +parts+ onto the document
def concat parts def concat(parts)
self.parts.concat parts self.parts.concat parts
end end
## ##
# Enumerator for the parts of this document # Enumerator for the parts of this document
def each &block def each(&block)
@parts.each(&block) @parts.each(&block)
end end
@ -94,7 +94,7 @@ class RDoc::Markup::Document
## ##
# The file this Document was created from. # The file this Document was created from.
def file= location def file=(location)
@file = case location @file = case location
when RDoc::TopLevel then when RDoc::TopLevel then
location.relative_name location.relative_name
@ -111,7 +111,7 @@ class RDoc::Markup::Document
# #
# The information in +other+ is preferred over the receiver # The information in +other+ is preferred over the receiver
def merge other def merge(other)
if empty? then if empty? then
@parts = other.parts @parts = other.parts
return self return self
@ -135,7 +135,7 @@ class RDoc::Markup::Document
RDoc::Markup::Document === @parts.first RDoc::Markup::Document === @parts.first
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
start = @file ? "[doc (#{@file}): " : '[doc: ' start = @file ? "[doc (#{@file}): " : '[doc: '
q.group 2, start, ']' do q.group 2, start, ']' do

View file

@ -21,7 +21,7 @@ class RDoc::Markup::Formatter
## ##
# Converts a target url to one that is relative to a given path # Converts a target url to one that is relative to a given path
def self.gen_relative_url path, target def self.gen_relative_url(path, target)
from = File.dirname path from = File.dirname path
to, to_file = File.split target to, to_file = File.split target
@ -45,7 +45,7 @@ class RDoc::Markup::Formatter
## ##
# Creates a new Formatter # Creates a new Formatter
def initialize options, markup = nil def initialize(options, markup = nil)
@options = options @options = options
@markup = markup || RDoc::Markup.new @markup = markup || RDoc::Markup.new
@ -66,7 +66,7 @@ class RDoc::Markup::Formatter
## ##
# Adds +document+ to the output # Adds +document+ to the output
def accept_document document def accept_document(document)
document.parts.each do |item| document.parts.each do |item|
case item case item
when RDoc::Markup::Document then # HACK when RDoc::Markup::Document then # HACK
@ -117,7 +117,7 @@ class RDoc::Markup::Formatter
## ##
# Marks up +content+ # Marks up +content+
def convert content def convert(content)
@markup.convert content, self @markup.convert content, self
end end
@ -147,7 +147,7 @@ class RDoc::Markup::Formatter
## ##
# Converts added regexp handlings. See RDoc::Markup#add_regexp_handling # Converts added regexp handlings. See RDoc::Markup#add_regexp_handling
def convert_regexp_handling target def convert_regexp_handling(target)
return target.text if in_tt? return target.text if in_tt?
handled = false handled = false
@ -173,7 +173,7 @@ class RDoc::Markup::Formatter
## ##
# Converts a string to be fancier if desired # Converts a string to be fancier if desired
def convert_string string def convert_string(string)
string string
end end
@ -195,7 +195,7 @@ class RDoc::Markup::Formatter
@in_tt > 0 @in_tt > 0
end end
def tt_tag? attr_mask, reverse = false def tt_tag?(attr_mask, reverse = false)
each_attr_tag(attr_mask, reverse) do |tag| each_attr_tag(attr_mask, reverse) do |tag|
return true if tt? tag return true if tt? tag
end end
@ -205,7 +205,7 @@ class RDoc::Markup::Formatter
## ##
# Turns on tags for +item+ on +res+ # Turns on tags for +item+ on +res+
def on_tags res, item def on_tags(res, item)
each_attr_tag(item.turn_on) do |tag| each_attr_tag(item.turn_on) do |tag|
res << annotate(tag.on) res << annotate(tag.on)
@in_tt += 1 if tt? tag @in_tt += 1 if tt? tag
@ -215,14 +215,14 @@ class RDoc::Markup::Formatter
## ##
# Turns off tags for +item+ on +res+ # Turns off tags for +item+ on +res+
def off_tags res, item def off_tags(res, item)
each_attr_tag(item.turn_off, true) do |tag| each_attr_tag(item.turn_off, true) do |tag|
@in_tt -= 1 if tt? tag @in_tt -= 1 if tt? tag
res << annotate(tag.off) res << annotate(tag.off)
end end
end end
def each_attr_tag attr_mask, reverse = false def each_attr_tag(attr_mask, reverse = false)
return if attr_mask.zero? return if attr_mask.zero?
@attr_tags.public_send(reverse ? :reverse_each : :each) do |tag| @attr_tags.public_send(reverse ? :reverse_each : :each) do |tag|
@ -235,7 +235,7 @@ class RDoc::Markup::Formatter
## ##
# Extracts and a scheme, url and an anchor id from +url+ and returns them. # Extracts and a scheme, url and an anchor id from +url+ and returns them.
def parse_url url def parse_url(url)
case url case url
when /^rdoc-label:([^:]*)(?::(.*))?/ then when /^rdoc-label:([^:]*)(?::(.*))?/ then
scheme = 'link' scheme = 'link'
@ -265,7 +265,7 @@ class RDoc::Markup::Formatter
## ##
# Is +tag+ a tt tag? # Is +tag+ a tt tag?
def tt? tag def tt?(tag)
tag.bit == @tt_bit tag.bit == @tt_bit
end end

View file

@ -16,15 +16,15 @@ class RDoc::Markup::HardBreak
## ##
# Calls #accept_hard_break on +visitor+ # Calls #accept_hard_break on +visitor+
def accept visitor def accept(visitor)
visitor.accept_hard_break self visitor.accept_hard_break self
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class === other self.class === other
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.text "[break]" q.text "[break]"
end end

View file

@ -27,7 +27,7 @@ RDoc::Markup::Heading =
@to_html = RDoc::Markup::ToHtml.new nil @to_html = RDoc::Markup::ToHtml.new nil
def @to_html.handle_regexp_CROSSREF target def @to_html.handle_regexp_CROSSREF(target)
target.text.sub(/^\\/, '') target.text.sub(/^\\/, '')
end end
@ -37,7 +37,7 @@ RDoc::Markup::Heading =
## ##
# Calls #accept_heading on +visitor+ # Calls #accept_heading on +visitor+
def accept visitor def accept(visitor)
visitor.accept_heading self visitor.accept_heading self
end end
@ -52,7 +52,7 @@ RDoc::Markup::Heading =
# Creates a fully-qualified label which will include the label from # Creates a fully-qualified label which will include the label from
# +context+. This helps keep ids unique in HTML. # +context+. This helps keep ids unique in HTML.
def label context = nil def label(context = nil)
label = aref label = aref
label = [context.aref, label].compact.join '-' if label = [context.aref, label].compact.join '-' if
@ -66,10 +66,16 @@ RDoc::Markup::Heading =
# element. # element.
def plain_html def plain_html
self.class.to_html.to_html(text.dup) text = self.text.dup
if matched = text.match(/rdoc-image:[^:]+:(.*)/)
text = matched[1]
end
self.class.to_html.to_html(text)
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[head: #{level} ", ']' do q.group 2, "[head: #{level} ", ']' do
q.pp text q.pp text
end end

View file

@ -20,17 +20,17 @@ class RDoc::Markup::Include
## ##
# Creates a new include that will import +file+ from +include_path+ # Creates a new include that will import +file+ from +include_path+
def initialize file, include_path def initialize(file, include_path)
@file = file @file = file
@include_path = include_path @include_path = include_path
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class === other and self.class === other and
@file == other.file and @include_path == other.include_path @file == other.file and @include_path == other.include_path
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, '[incl ', ']' do q.group 2, '[incl ', ']' do
q.text file q.text file
q.breakable q.breakable

View file

@ -19,14 +19,14 @@ class RDoc::Markup::IndentedParagraph < RDoc::Markup::Raw
super(*parts) super(*parts)
end end
def == other # :nodoc: def ==(other) # :nodoc:
super and indent == other.indent super and indent == other.indent
end end
## ##
# Calls #accept_indented_paragraph on +visitor+ # Calls #accept_indented_paragraph on +visitor+
def accept visitor def accept(visitor)
visitor.accept_indented_paragraph self visitor.accept_indented_paragraph self
end end
@ -34,7 +34,7 @@ class RDoc::Markup::IndentedParagraph < RDoc::Markup::Raw
# Joins the raw paragraph text and converts inline HardBreaks to the # Joins the raw paragraph text and converts inline HardBreaks to the
# +hard_break+ text followed by the indent. # +hard_break+ text followed by the indent.
def text hard_break = nil def text(hard_break = nil)
@parts.map do |part| @parts.map do |part|
if RDoc::Markup::HardBreak === part then if RDoc::Markup::HardBreak === part then
'%1$s%3$*2$s' % [hard_break, @indent, ' '] if hard_break '%1$s%3$*2$s' % [hard_break, @indent, ' '] if hard_break

View file

@ -46,11 +46,11 @@ class RDoc::Markup::List
## ##
# Appends +item+ to the list # Appends +item+ to the list
def << item def <<(item)
@items << item @items << item
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class == other.class and self.class == other.class and
@type == other.type and @type == other.type and
@items == other.items @items == other.items
@ -59,7 +59,7 @@ class RDoc::Markup::List
## ##
# Runs this list and all its #items through +visitor+ # Runs this list and all its #items through +visitor+
def accept visitor def accept(visitor)
visitor.accept_list_start self visitor.accept_list_start self
@items.each do |item| @items.each do |item|
@ -83,7 +83,7 @@ class RDoc::Markup::List
@items.last @items.last
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, "[list: #{@type} ", ']' do q.group 2, "[list: #{@type} ", ']' do
q.seplist @items do |item| q.seplist @items do |item|
q.pp item q.pp item

View file

@ -33,11 +33,11 @@ class RDoc::Markup::ListItem
## ##
# Appends +part+ to the ListItem # Appends +part+ to the ListItem
def << part def <<(part)
@parts << part @parts << part
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class == other.class and self.class == other.class and
@label == other.label and @label == other.label and
@parts == other.parts @parts == other.parts
@ -46,7 +46,7 @@ class RDoc::Markup::ListItem
## ##
# Runs this list item and all its #parts through +visitor+ # Runs this list item and all its #parts through +visitor+
def accept visitor def accept(visitor)
visitor.accept_list_item_start self visitor.accept_list_item_start self
@parts.each do |part| @parts.each do |part|
@ -70,7 +70,7 @@ class RDoc::Markup::ListItem
@parts.length @parts.length
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, '[item: ', ']' do q.group 2, '[item: ', ']' do
case @label case @label
when Array then when Array then

View file

@ -7,7 +7,7 @@ class RDoc::Markup::Paragraph < RDoc::Markup::Raw
## ##
# Calls #accept_paragraph on +visitor+ # Calls #accept_paragraph on +visitor+
def accept visitor def accept(visitor)
visitor.accept_paragraph self visitor.accept_paragraph self
end end
@ -15,7 +15,7 @@ class RDoc::Markup::Paragraph < RDoc::Markup::Raw
# Joins the raw paragraph text and converts inline HardBreaks to the # Joins the raw paragraph text and converts inline HardBreaks to the
# +hard_break+ text. # +hard_break+ text.
def text hard_break = '' def text(hard_break = '')
@parts.map do |part| @parts.map do |part|
if RDoc::Markup::HardBreak === part then if RDoc::Markup::HardBreak === part then
hard_break hard_break

View file

@ -57,7 +57,7 @@ class RDoc::Markup::Parser
# #
# Use RDoc::Markup#parse instead of this method. # Use RDoc::Markup#parse instead of this method.
def self.parse str def self.parse(str)
parser = new parser = new
parser.tokenize str parser.tokenize str
doc = RDoc::Markup::Document.new doc = RDoc::Markup::Document.new
@ -67,7 +67,7 @@ class RDoc::Markup::Parser
## ##
# Returns a token stream for +str+, for testing # Returns a token stream for +str+, for testing
def self.tokenize str def self.tokenize(str)
parser = new parser = new
parser.tokenize str parser.tokenize str
parser.tokens parser.tokens
@ -87,7 +87,7 @@ class RDoc::Markup::Parser
## ##
# Builds a Heading of +level+ # Builds a Heading of +level+
def build_heading level def build_heading(level)
type, text, = get type, text, = get
text = case type text = case type
@ -105,7 +105,7 @@ class RDoc::Markup::Parser
## ##
# Builds a List flush to +margin+ # Builds a List flush to +margin+
def build_list margin def build_list(margin)
p :list_start => margin if @debug p :list_start => margin if @debug
list = RDoc::Markup::List.new list = RDoc::Markup::List.new
@ -205,7 +205,7 @@ class RDoc::Markup::Parser
## ##
# Builds a Paragraph that is flush to +margin+ # Builds a Paragraph that is flush to +margin+
def build_paragraph margin def build_paragraph(margin)
p :paragraph_start => margin if @debug p :paragraph_start => margin if @debug
paragraph = RDoc::Markup::Paragraph.new paragraph = RDoc::Markup::Paragraph.new
@ -240,7 +240,7 @@ class RDoc::Markup::Parser
# terminated by a newline. Blank lines always consist of a single newline # terminated by a newline. Blank lines always consist of a single newline
# character, and there is never a single newline at the end of the verbatim. # character, and there is never a single newline at the end of the verbatim.
def build_verbatim margin def build_verbatim(margin)
p :verbatim_begin => margin if @debug p :verbatim_begin => margin if @debug
verbatim = RDoc::Markup::Verbatim.new verbatim = RDoc::Markup::Verbatim.new
@ -339,7 +339,7 @@ class RDoc::Markup::Parser
# #
# Returns +parent+. # Returns +parent+.
def parse parent, indent = 0 def parse(parent, indent = 0)
p :parse_start => indent if @debug p :parse_start => indent if @debug
until @tokens.empty? do until @tokens.empty? do
@ -403,7 +403,7 @@ class RDoc::Markup::Parser
## ##
# Small hook that is overridden by RDoc::TomDoc # Small hook that is overridden by RDoc::TomDoc
def parse_text parent, indent # :nodoc: def parse_text(parent, indent) # :nodoc:
parent << build_paragraph(indent) parent << build_paragraph(indent)
end end
@ -465,7 +465,7 @@ class RDoc::Markup::Parser
## ##
# Creates the StringScanner # Creates the StringScanner
def setup_scanner input def setup_scanner(input)
@s = MyStringScanner.new input @s = MyStringScanner.new input
end end
@ -474,7 +474,7 @@ class RDoc::Markup::Parser
# #
# Optionally raises an error if the next token is not of the expected type. # Optionally raises an error if the next token is not of the expected type.
def skip token_type, error = true def skip(token_type, error = true)
type, = get type, = get
return unless type # end of stream return unless type # end of stream
return @current_token if token_type == type return @current_token if token_type == type
@ -485,7 +485,7 @@ class RDoc::Markup::Parser
## ##
# Turns text +input+ into a stream of tokens # Turns text +input+ into a stream of tokens
def tokenize input def tokenize(input)
setup_scanner input setup_scanner input
until @s.eos? do until @s.eos? do

View file

@ -27,7 +27,7 @@ class RDoc::Markup::PreProcess
# with the result RDoc::Comment (or text String) and the code object for the # with the result RDoc::Comment (or text String) and the code object for the
# comment (if any). # comment (if any).
def self.post_process &block def self.post_process(&block)
@post_processors << block @post_processors << block
end end
@ -50,7 +50,7 @@ class RDoc::Markup::PreProcess
# # replace text, etc. # # replace text, etc.
# end # end
def self.register directive, &block def self.register(directive, &block)
@registered[directive] = block @registered[directive] = block
end end
@ -96,7 +96,7 @@ class RDoc::Markup::PreProcess
# directive's parameter is set as metadata on the +code_object+. See # directive's parameter is set as metadata on the +code_object+. See
# RDoc::CodeObject#metadata for details. # RDoc::CodeObject#metadata for details.
def handle text, code_object = nil, &block def handle(text, code_object = nil, &block)
first_line = 1 first_line = 1
if RDoc::Comment === text then if RDoc::Comment === text then
comment = text comment = text
@ -150,8 +150,8 @@ class RDoc::Markup::PreProcess
#-- #--
# When 1.8.7 support is ditched prefix can be defaulted to '' # When 1.8.7 support is ditched prefix can be defaulted to ''
def handle_directive prefix, directive, param, code_object = nil, def handle_directive(prefix, directive, param, code_object = nil,
encoding = nil, line = nil encoding = nil, line = nil)
blankline = "#{prefix.strip}\n" blankline = "#{prefix.strip}\n"
directive = directive.downcase directive = directive.downcase
@ -279,7 +279,7 @@ class RDoc::Markup::PreProcess
# TODO shift left the whole file content in that case # TODO shift left the whole file content in that case
# TODO comment stop/start #-- and #++ in included file must be processed here # TODO comment stop/start #-- and #++ in included file must be processed here
def include_file name, indent, encoding def include_file(name, indent, encoding)
full_name = find_include_file name full_name = find_include_file name
unless full_name then unless full_name then

View file

@ -20,29 +20,29 @@ class RDoc::Markup::Raw
## ##
# Appends +text+ # Appends +text+
def << text def <<(text)
@parts << text @parts << text
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class == other.class and @parts == other.parts self.class == other.class and @parts == other.parts
end end
## ##
# Calls #accept_raw+ on +visitor+ # Calls #accept_raw+ on +visitor+
def accept visitor def accept(visitor)
visitor.accept_raw self visitor.accept_raw self
end end
## ##
# Appends +other+'s parts # Appends +other+'s parts
def merge other def merge(other)
@parts.concat other.parts @parts.concat other.parts
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
self.class.name =~ /.*::(\w{1,4})/i self.class.name =~ /.*::(\w{1,4})/i
q.group 2, "[#{$1.downcase}: ", ']' do q.group 2, "[#{$1.downcase}: ", ']' do

View file

@ -7,11 +7,11 @@ class RDoc::Markup::Rule < Struct.new :weight
## ##
# Calls #accept_rule on +visitor+ # Calls #accept_rule on +visitor+
def accept visitor def accept(visitor)
visitor.accept_rule self visitor.accept_rule self
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group 2, '[rule:', ']' do q.group 2, '[rule:', ']' do
q.pp weight q.pp weight
end end

View file

@ -13,23 +13,23 @@ class RDoc::Markup::Table
attr_accessor :body attr_accessor :body
# Creates new instance # Creates new instance
def initialize header, align, body def initialize(header, align, body)
@header, @align, @body = header, align, body @header, @align, @body = header, align, body
end end
# :stopdoc: # :stopdoc:
def == other def ==(other)
self.class == other.class and self.class == other.class and
@header == other.header and @header == other.header and
@align == other.align and @align == other.align and
@body == other.body @body == other.body
end end
def accept visitor def accept(visitor)
visitor.accept_table @header, @body, @align visitor.accept_table @header, @body, @align
end end
def pretty_print q def pretty_print(q)
q.group 2, '[Table: ', ']' do q.group 2, '[Table: ', ']' do
q.group 2, '[Head: ', ']' do q.group 2, '[Head: ', ']' do
q.seplist @header.zip(@align) do |text, align| q.seplist @header.zip(@align) do |text, align|

View file

@ -7,7 +7,7 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
## ##
# Creates a new ToAnsi visitor that is ready to output vibrant ANSI color! # Creates a new ToAnsi visitor that is ready to output vibrant ANSI color!
def initialize markup = nil def initialize(markup = nil)
super super
@headings.clear @headings.clear
@ -28,7 +28,7 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
## ##
# Overrides indent width to ensure output lines up correctly. # Overrides indent width to ensure output lines up correctly.
def accept_list_item_end list_item def accept_list_item_end(list_item)
width = case @list_type.last width = case @list_type.last
when :BULLET then when :BULLET then
2 2
@ -52,7 +52,7 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
## ##
# Adds coloring to note and label list items # Adds coloring to note and label list items
def accept_list_item_start list_item def accept_list_item_start(list_item)
bullet = case @list_type.last bullet = case @list_type.last
when :BULLET then when :BULLET then
'*' '*'

View file

@ -10,7 +10,7 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
## ##
# Returns a new ToBs that is ready for hot backspace action! # Returns a new ToBs that is ready for hot backspace action!
def initialize markup = nil def initialize(markup = nil)
super super
@in_b = false @in_b = false
@ -30,7 +30,7 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
## ##
# Makes heading text bold. # Makes heading text bold.
def accept_heading heading def accept_heading(heading)
use_prefix or @res << ' ' * @indent use_prefix or @res << ' ' * @indent
@res << @headings[heading.level][0] @res << @headings[heading.level][0]
@in_b = true @in_b = true
@ -43,7 +43,7 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
## ##
# Prepares the visitor for consuming +list_item+ # Prepares the visitor for consuming +list_item+
def accept_list_item_start list_item def accept_list_item_start(list_item)
type = @list_type.last type = @list_type.last
case type case type
@ -68,7 +68,7 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
## ##
# Turns on or off regexp handling for +convert_string+ # Turns on or off regexp handling for +convert_string+
def annotate tag def annotate(tag)
case tag case tag
when '+b' then @in_b = true when '+b' then @in_b = true
when '-b' then @in_b = false when '-b' then @in_b = false
@ -81,14 +81,14 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
## ##
# Calls convert_string on the result of convert_regexp_handling # Calls convert_string on the result of convert_regexp_handling
def convert_regexp_handling target def convert_regexp_handling(target)
convert_string super convert_string super
end end
## ##
# Adds bold or underline mixed with backspaces # Adds bold or underline mixed with backspaces
def convert_string string def convert_string(string)
return string unless @in_b or @in_em return string unless @in_b or @in_em
chars = if @in_b then chars = if @in_b then
string.chars.map do |char| "#{char}\b#{char}" end string.chars.map do |char| "#{char}\b#{char}" end

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'cgi/util' require 'cgi/escape'
# For CGI.unescape on earlier rubies
require 'cgi/util' if RUBY_VERSION < '3.5'
## ##
# Outputs RDoc markup as HTML. # Outputs RDoc markup as HTML.
@ -42,7 +44,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Creates a new formatter that will output HTML # Creates a new formatter that will output HTML
def initialize options, markup = nil def initialize(options, markup = nil)
super super
@code_object = nil @code_object = nil
@ -82,7 +84,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
add_regexp_handling_TIDYLINK add_regexp_handling_TIDYLINK
end end
def handle_RDOCLINK url # :nodoc: def handle_RDOCLINK(url) # :nodoc:
case url case url
when /^rdoc-ref:/ when /^rdoc-ref:/
CGI.escapeHTML($') CGI.escapeHTML($')
@ -98,7 +100,15 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
gen_url CGI.escapeHTML(url), CGI.escapeHTML(text) gen_url CGI.escapeHTML(url), CGI.escapeHTML(text)
when /^rdoc-image:/ when /^rdoc-image:/
%[<img src=\"#{CGI.escapeHTML($')}\">] # Split the string after "rdoc-image:" into url and alt.
# "path/to/image.jpg:alt text" => ["path/to/image.jpg", "alt text"]
# "http://example.com/path/to/image.jpg:alt text" => ["http://example.com/path/to/image.jpg", "alt text"]
url, alt = $'.split(/:(?!\/)/, 2)
if alt && !alt.empty?
%[<img src="#{CGI.escapeHTML(url)}" alt="#{CGI.escapeHTML(alt)}">]
else
%[<img src="#{CGI.escapeHTML(url)}">]
end
when /\Ardoc-[a-z]+:/ when /\Ardoc-[a-z]+:/
CGI.escapeHTML($') CGI.escapeHTML($')
end end
@ -107,7 +117,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# +target+ is a <code><br></code> # +target+ is a <code><br></code>
def handle_regexp_HARD_BREAK target def handle_regexp_HARD_BREAK(target)
'<br>' '<br>'
end end
@ -138,7 +148,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
# For the +rdoc-label+ scheme the footnote and label prefixes are stripped # For the +rdoc-label+ scheme the footnote and label prefixes are stripped
# when creating a link. All other contents will be linked verbatim. # when creating a link. All other contents will be linked verbatim.
def handle_regexp_RDOCLINK target def handle_regexp_RDOCLINK(target)
handle_RDOCLINK target.text handle_RDOCLINK target.text
end end
@ -187,7 +197,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Adds +block_quote+ to the output # Adds +block_quote+ to the output
def accept_block_quote block_quote def accept_block_quote(block_quote)
@res << "\n<blockquote>" @res << "\n<blockquote>"
block_quote.parts.each do |part| block_quote.parts.each do |part|
@ -200,7 +210,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Adds +paragraph+ to the output # Adds +paragraph+ to the output
def accept_paragraph paragraph def accept_paragraph(paragraph)
@res << "\n<p>" @res << "\n<p>"
text = paragraph.text @hard_break text = paragraph.text @hard_break
text = text.gsub(/(#{SPACE_SEPARATED_LETTER_CLASS})?\K\r?\n(?=(?(1)(#{SPACE_SEPARATED_LETTER_CLASS})?))/o) { text = text.gsub(/(#{SPACE_SEPARATED_LETTER_CLASS})?\K\r?\n(?=(?(1)(#{SPACE_SEPARATED_LETTER_CLASS})?))/o) {
@ -213,7 +223,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Adds +verbatim+ to the output # Adds +verbatim+ to the output
def accept_verbatim verbatim def accept_verbatim(verbatim)
text = verbatim.text.rstrip text = verbatim.text.rstrip
klass = nil klass = nil
@ -243,7 +253,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Adds +rule+ to the output # Adds +rule+ to the output
def accept_rule rule def accept_rule(rule)
@res << "<hr>\n" @res << "<hr>\n"
end end
@ -296,7 +306,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
# Adds +heading+ to the output. The headings greater than 6 are trimmed to # Adds +heading+ to the output. The headings greater than 6 are trimmed to
# level 6. # level 6.
def accept_heading heading def accept_heading(heading)
level = [6, heading.level].min level = [6, heading.level].min
label = heading.label @code_object label = heading.label @code_object
@ -317,14 +327,14 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Adds +raw+ to the output # Adds +raw+ to the output
def accept_raw raw def accept_raw(raw)
@res << raw.parts.join("\n") @res << raw.parts.join("\n")
end end
## ##
# Adds +table+ to the output # Adds +table+ to the output
def accept_table header, body, aligns def accept_table(header, body, aligns)
@res << "\n<table role=\"table\">\n<thead>\n<tr>\n" @res << "\n<table role=\"table\">\n<thead>\n<tr>\n"
header.zip(aligns) do |text, align| header.zip(aligns) do |text, align|
@res << '<th' @res << '<th'
@ -357,7 +367,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
# Generate a link to +url+ with content +text+. Handles the special cases # Generate a link to +url+ with content +text+. Handles the special cases
# for img: and link: described under handle_regexp_HYPERLINK # for img: and link: described under handle_regexp_HYPERLINK
def gen_url url, text def gen_url(url, text)
scheme, url, id = parse_url url scheme, url, id = parse_url url
if %w[http https link].include?(scheme) and if %w[http https link].include?(scheme) and
@ -431,7 +441,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Returns true if text is valid ruby syntax # Returns true if text is valid ruby syntax
def parseable? text def parseable?(text)
verbose, $VERBOSE = $VERBOSE, nil verbose, $VERBOSE = $VERBOSE, nil
catch(:valid) do catch(:valid) do
eval("BEGIN { throw :valid, true }\n#{text}") eval("BEGIN { throw :valid, true }\n#{text}")
@ -445,7 +455,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
## ##
# Converts +item+ to HTML using RDoc::Text#to_html # Converts +item+ to HTML using RDoc::Text#to_html
def to_html item def to_html(item)
super convert_flow @am.flow item super convert_flow @am.flow item
end end

View file

@ -58,7 +58,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
# Creates a link to the reference +name+ if the name exists. If +text+ is # Creates a link to the reference +name+ if the name exists. If +text+ is
# given it is used as the link text, otherwise +name+ is used. # given it is used as the link text, otherwise +name+ is used.
def cross_reference name, text = nil, code = true, rdoc_ref: false def cross_reference(name, text = nil, code = true, rdoc_ref: false)
lookup = name lookup = name
name = name[1..-1] unless @show_hash if name[0, 1] == '#' name = name[1..-1] unless @show_hash if name[0, 1] == '#'
@ -83,6 +83,8 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
def handle_regexp_CROSSREF(target) def handle_regexp_CROSSREF(target)
name = target.text name = target.text
return name if @options.autolink_excluded_words&.include?(name)
return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails
unless @hyperlink_all then unless @hyperlink_all then
@ -99,7 +101,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
# Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to # Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to
# handle other schemes. # handle other schemes.
def handle_regexp_HYPERLINK target def handle_regexp_HYPERLINK(target)
url = target.text url = target.text
case url case url
@ -118,7 +120,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
# All other contents are handled by # All other contents are handled by
# {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK] # {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK]
def handle_regexp_RDOCLINK target def handle_regexp_RDOCLINK(target)
url = target.text url = target.text
case url case url
@ -133,7 +135,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
# Generates links for <tt>rdoc-ref:</tt> scheme URLs and allows # Generates links for <tt>rdoc-ref:</tt> scheme URLs and allows
# RDoc::Markup::ToHtml to handle other schemes. # RDoc::Markup::ToHtml to handle other schemes.
def gen_url url, text def gen_url(url, text)
if url =~ /\Ardoc-ref:/ if url =~ /\Ardoc-ref:/
name = $' name = $'
cross_reference name, text, name == text, rdoc_ref: true cross_reference name, text, name == text, rdoc_ref: true
@ -145,7 +147,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
## ##
# Creates an HTML link to +name+ with the given +text+. # Creates an HTML link to +name+ with the given +text+.
def link name, text, code = true, rdoc_ref: false def link(name, text, code = true, rdoc_ref: false)
if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])?@/ if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])?@/
name = $1 name = $1
label = $' label = $'

View file

@ -34,7 +34,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
# next word boundary after the given number of +characters+ or +paragraphs+ # next word boundary after the given number of +characters+ or +paragraphs+
# of text have been encountered. # of text have been encountered.
def initialize options, characters = 100, paragraphs = 3, markup = nil def initialize(options, characters = 100, paragraphs = 3, markup = nil)
super options, markup super options, markup
@character_limit = characters @character_limit = characters
@ -50,7 +50,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Adds +heading+ to the output as a paragraph # Adds +heading+ to the output as a paragraph
def accept_heading heading def accept_heading(heading)
@res << "<p>#{to_html heading.text}\n" @res << "<p>#{to_html heading.text}\n"
add_paragraph add_paragraph
@ -69,7 +69,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Adds +paragraph+ to the output # Adds +paragraph+ to the output
def accept_paragraph paragraph def accept_paragraph(paragraph)
para = @in_list_entry.last || "<p>" para = @in_list_entry.last || "<p>"
text = paragraph.text @hard_break text = paragraph.text @hard_break
@ -82,20 +82,20 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Finishes consumption of +list_item+ # Finishes consumption of +list_item+
def accept_list_item_end list_item def accept_list_item_end(list_item)
end end
## ##
# Prepares the visitor for consuming +list_item+ # Prepares the visitor for consuming +list_item+
def accept_list_item_start list_item def accept_list_item_start(list_item)
@res << list_item_start(list_item, @list.last) @res << list_item_start(list_item, @list.last)
end end
## ##
# Prepares the visitor for consuming +list+ # Prepares the visitor for consuming +list+
def accept_list_start list def accept_list_start(list)
@list << list.type @list << list.type
@res << html_list_name(list.type, true) @res << html_list_name(list.type, true)
@in_list_entry.push '' @in_list_entry.push ''
@ -104,7 +104,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Adds +verbatim+ to the output # Adds +verbatim+ to the output
def accept_verbatim verbatim def accept_verbatim(verbatim)
throw :done if @characters >= @character_limit throw :done if @characters >= @character_limit
input = verbatim.text.rstrip input = verbatim.text.rstrip
@ -128,14 +128,14 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Removes escaping from the cross-references in +target+ # Removes escaping from the cross-references in +target+
def handle_regexp_CROSSREF target def handle_regexp_CROSSREF(target)
target.text.sub(/\A\\/, '') target.text.sub(/\A\\/, '')
end end
## ##
# +target+ is a <code><br></code> # +target+ is a <code><br></code>
def handle_regexp_HARD_BREAK target def handle_regexp_HARD_BREAK(target)
@characters -= 4 @characters -= 4
'<br>' '<br>'
end end
@ -143,7 +143,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Lists are paragraphs, but notes and labels have a separator # Lists are paragraphs, but notes and labels have a separator
def list_item_start list_item, list_type def list_item_start(list_item, list_type)
throw :done if @characters >= @character_limit throw :done if @characters >= @character_limit
case list_type case list_type
@ -168,7 +168,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
# Returns just the text of +link+, +url+ is only used to determine the link # Returns just the text of +link+, +url+ is only used to determine the link
# type. # type.
def gen_url url, text def gen_url(url, text)
if url =~ /^rdoc-label:([^:]*)(?::(.*))?/ then if url =~ /^rdoc-label:([^:]*)(?::(.*))?/ then
type = "link" type = "link"
elsif url =~ /([A-Za-z]+):(.*)/ then elsif url =~ /([A-Za-z]+):(.*)/ then
@ -188,7 +188,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# In snippets, there are no lists # In snippets, there are no lists
def html_list_name list_type, open_tag def html_list_name(list_type, open_tag)
'' ''
end end
@ -204,7 +204,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Marks up +content+ # Marks up +content+
def convert content def convert(content)
catch :done do catch :done do
return super return super
end end
@ -215,7 +215,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Converts flow items +flow+ # Converts flow items +flow+
def convert_flow flow def convert_flow(flow)
throw :done if @characters >= @character_limit throw :done if @characters >= @character_limit
res = [] res = []
@ -251,7 +251,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
# Maintains a bitmask to allow HTML elements to be closed properly. See # Maintains a bitmask to allow HTML elements to be closed properly. See
# RDoc::Markup::Formatter. # RDoc::Markup::Formatter.
def on_tags res, item def on_tags(res, item)
@mask ^= item.turn_on @mask ^= item.turn_on
super super
@ -261,7 +261,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
# Maintains a bitmask to allow HTML elements to be closed properly. See # Maintains a bitmask to allow HTML elements to be closed properly. See
# RDoc::Markup::Formatter. # RDoc::Markup::Formatter.
def off_tags res, item def off_tags(res, item)
@mask ^= item.turn_off @mask ^= item.turn_off
super super
@ -270,7 +270,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
## ##
# Truncates +text+ at the end of the first word after the character_limit. # Truncates +text+ at the end of the first word after the character_limit.
def truncate text def truncate(text)
length = text.length length = text.length
characters = @characters characters = @characters
@characters += length @characters += length

View file

@ -22,7 +22,7 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
## ##
# Converts the parts of +paragraph+ to a single entry. # Converts the parts of +paragraph+ to a single entry.
def accept_paragraph paragraph def accept_paragraph(paragraph)
parts = paragraph.parts.chunk do |part| parts = paragraph.parts.chunk do |part|
String === part String === part
end.flat_map do |string, chunk| end.flat_map do |string, chunk|

View file

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'cgi/util' require 'cgi/escape'
## ##
# Creates HTML-safe labels suitable for use in id attributes. Tidylinks are # Creates HTML-safe labels suitable for use in id attributes. Tidylinks are
@ -13,7 +13,7 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
## ##
# Creates a new formatter that will output HTML-safe labels # Creates a new formatter that will output HTML-safe labels
def initialize markup = nil def initialize(markup = nil)
super nil, markup super nil, markup
@markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF @markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
@ -29,7 +29,7 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
## ##
# Converts +text+ to an HTML-safe label # Converts +text+ to an HTML-safe label
def convert text def convert(text)
label = convert_flow @am.flow text label = convert_flow @am.flow text
CGI.escape(label).gsub('%', '-').sub(/^-/, '') CGI.escape(label).gsub('%', '-').sub(/^-/, '')
@ -39,7 +39,7 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
# Converts the CROSSREF +target+ to plain text, removing the suppression # Converts the CROSSREF +target+ to plain text, removing the suppression
# marker, if any # marker, if any
def handle_regexp_CROSSREF target def handle_regexp_CROSSREF(target)
text = target.text text = target.text
text.sub(/^\\/, '') text.sub(/^\\/, '')
@ -48,7 +48,7 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
## ##
# Converts the TIDYLINK +target+ to just the text part # Converts the TIDYLINK +target+ to just the text part
def handle_regexp_TIDYLINK target def handle_regexp_TIDYLINK(target)
text = target.text text = target.text
return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/ return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/

View file

@ -9,7 +9,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Creates a new formatter that will output Markdown format text # Creates a new formatter that will output Markdown format text
def initialize markup = nil def initialize(markup = nil)
super super
@headings[1] = ['# ', ''] @headings[1] = ['# ', '']
@ -37,21 +37,21 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Adds a newline to the output # Adds a newline to the output
def handle_regexp_HARD_BREAK target def handle_regexp_HARD_BREAK(target)
" \n" " \n"
end end
## ##
# Finishes consumption of `list` # Finishes consumption of `list`
def accept_list_end list def accept_list_end(list)
super super
end end
## ##
# Finishes consumption of `list_item` # Finishes consumption of `list_item`
def accept_list_item_end list_item def accept_list_item_end(list_item)
width = case @list_type.last width = case @list_type.last
when :BULLET then when :BULLET then
4 4
@ -72,7 +72,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Prepares the visitor for consuming `list_item` # Prepares the visitor for consuming `list_item`
def accept_list_item_start list_item def accept_list_item_start(list_item)
type = @list_type.last type = @list_type.last
case type case type
@ -97,7 +97,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Prepares the visitor for consuming `list` # Prepares the visitor for consuming `list`
def accept_list_start list def accept_list_start(list)
case list.type case list.type
when :BULLET, :LABEL, :NOTE then when :BULLET, :LABEL, :NOTE then
@list_index << nil @list_index << nil
@ -114,7 +114,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Adds `rule` to the output # Adds `rule` to the output
def accept_rule rule def accept_rule(rule)
use_prefix or @res << ' ' * @indent use_prefix or @res << ' ' * @indent
@res << '-' * 3 @res << '-' * 3
@res << "\n" @res << "\n"
@ -123,7 +123,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Outputs `verbatim` indented 4 columns # Outputs `verbatim` indented 4 columns
def accept_verbatim verbatim def accept_verbatim(verbatim)
indent = ' ' * (@indent + 4) indent = ' ' * (@indent + 4)
verbatim.parts.each do |part| verbatim.parts.each do |part|
@ -137,7 +137,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Creates a Markdown-style URL from +url+ with +text+. # Creates a Markdown-style URL from +url+ with +text+.
def gen_url url, text def gen_url(url, text)
scheme, url, = parse_url url scheme, url, = parse_url url
"[#{text.sub(%r{^#{scheme}:/*}i, '')}](#{url})" "[#{text.sub(%r{^#{scheme}:/*}i, '')}](#{url})"
@ -146,7 +146,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Handles <tt>rdoc-</tt> type links for footnotes. # Handles <tt>rdoc-</tt> type links for footnotes.
def handle_rdoc_link url def handle_rdoc_link(url)
case url case url
when /^rdoc-ref:/ then when /^rdoc-ref:/ then
$' $'
@ -166,7 +166,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Converts the RDoc markup tidylink into a Markdown.style link. # Converts the RDoc markup tidylink into a Markdown.style link.
def handle_regexp_TIDYLINK target def handle_regexp_TIDYLINK(target)
text = target.text text = target.text
return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/ return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
@ -184,7 +184,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
## ##
# Converts the rdoc-...: links into a Markdown.style links. # Converts the rdoc-...: links into a Markdown.style links.
def handle_regexp_RDOCLINK target def handle_regexp_RDOCLINK(target)
handle_rdoc_link target.text handle_rdoc_link target.text
end end

View file

@ -3,6 +3,16 @@
# Outputs RDoc markup as RDoc markup! (mostly) # Outputs RDoc markup as RDoc markup! (mostly)
class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
DEFAULT_HEADINGS = {
1 => ['= ', ''],
2 => ['== ', ''],
3 => ['=== ', ''],
4 => ['==== ', ''],
5 => ['===== ', ''],
6 => ['====== ', '']
}
DEFAULT_HEADINGS.default = []
DEFAULT_HEADINGS.freeze
## ##
# Current indent amount for output in characters # Current indent amount for output in characters
@ -42,23 +52,14 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Creates a new formatter that will output (mostly) \RDoc markup # Creates a new formatter that will output (mostly) \RDoc markup
def initialize markup = nil def initialize(markup = nil)
super nil, markup super nil, markup
@markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF) @markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF)
@width = 78 @width = 78
init_tags init_tags
@headings = {} @headings = DEFAULT_HEADINGS.dup
@headings.default = []
@headings[1] = ['= ', '']
@headings[2] = ['== ', '']
@headings[3] = ['=== ', '']
@headings[4] = ['==== ', '']
@headings[5] = ['===== ', '']
@headings[6] = ['====== ', '']
@hard_break = "\n" @hard_break = "\n"
end end
@ -74,14 +75,14 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds +blank_line+ to the output # Adds +blank_line+ to the output
def accept_blank_line blank_line def accept_blank_line(blank_line)
@res << "\n" @res << "\n"
end end
## ##
# Adds +paragraph+ to the output # Adds +paragraph+ to the output
def accept_block_quote block_quote def accept_block_quote(block_quote)
@indent += 2 @indent += 2
block_quote.parts.each do |part| block_quote.parts.each do |part|
@ -96,7 +97,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds +heading+ to the output # Adds +heading+ to the output
def accept_heading heading def accept_heading(heading)
use_prefix or @res << ' ' * @indent use_prefix or @res << ' ' * @indent
@res << @headings[heading.level][0] @res << @headings[heading.level][0]
@res << attributes(heading.text) @res << attributes(heading.text)
@ -107,7 +108,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Finishes consumption of +list+ # Finishes consumption of +list+
def accept_list_end list def accept_list_end(list)
@list_index.pop @list_index.pop
@list_type.pop @list_type.pop
@list_width.pop @list_width.pop
@ -116,7 +117,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Finishes consumption of +list_item+ # Finishes consumption of +list_item+
def accept_list_item_end list_item def accept_list_item_end(list_item)
width = case @list_type.last width = case @list_type.last
when :BULLET then when :BULLET then
2 2
@ -140,7 +141,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Prepares the visitor for consuming +list_item+ # Prepares the visitor for consuming +list_item+
def accept_list_item_start list_item def accept_list_item_start(list_item)
type = @list_type.last type = @list_type.last
case type case type
@ -173,7 +174,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Prepares the visitor for consuming +list+ # Prepares the visitor for consuming +list+
def accept_list_start list def accept_list_start(list)
case list.type case list.type
when :BULLET then when :BULLET then
@list_index << nil @list_index << nil
@ -200,7 +201,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds +paragraph+ to the output # Adds +paragraph+ to the output
def accept_paragraph paragraph def accept_paragraph(paragraph)
text = paragraph.text @hard_break text = paragraph.text @hard_break
wrap attributes text wrap attributes text
end end
@ -208,7 +209,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds +paragraph+ to the output # Adds +paragraph+ to the output
def accept_indented_paragraph paragraph def accept_indented_paragraph(paragraph)
@indent += paragraph.indent @indent += paragraph.indent
text = paragraph.text @hard_break text = paragraph.text @hard_break
wrap attributes text wrap attributes text
@ -218,14 +219,14 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds +raw+ to the output # Adds +raw+ to the output
def accept_raw raw def accept_raw(raw)
@res << raw.parts.join("\n") @res << raw.parts.join("\n")
end end
## ##
# Adds +rule+ to the output # Adds +rule+ to the output
def accept_rule rule def accept_rule(rule)
use_prefix or @res << ' ' * @indent use_prefix or @res << ' ' * @indent
@res << '-' * (@width - @indent) @res << '-' * (@width - @indent)
@res << "\n" @res << "\n"
@ -234,7 +235,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Outputs +verbatim+ indented 2 columns # Outputs +verbatim+ indented 2 columns
def accept_verbatim verbatim def accept_verbatim(verbatim)
indent = ' ' * (@indent + 2) indent = ' ' * (@indent + 2)
verbatim.parts.each do |part| verbatim.parts.each do |part|
@ -248,7 +249,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds +table+ to the output # Adds +table+ to the output
def accept_table header, body, aligns def accept_table(header, body, aligns)
widths = header.zip(*body).map do |cols| widths = header.zip(*body).map do |cols|
cols.map(&:size).max cols.map(&:size).max
end end
@ -276,7 +277,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Applies attribute-specific markup to +text+ using RDoc::AttributeManager # Applies attribute-specific markup to +text+ using RDoc::AttributeManager
def attributes text def attributes(text)
flow = @am.flow text.dup flow = @am.flow text.dup
convert_flow flow convert_flow flow
end end
@ -291,7 +292,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Removes preceding \\ from the suppressed crossref +target+ # Removes preceding \\ from the suppressed crossref +target+
def handle_regexp_SUPPRESSED_CROSSREF target def handle_regexp_SUPPRESSED_CROSSREF(target)
text = target.text text = target.text
text = text.sub('\\', '') unless in_tt? text = text.sub('\\', '') unless in_tt?
text text
@ -300,7 +301,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Adds a newline to the output # Adds a newline to the output
def handle_regexp_HARD_BREAK target def handle_regexp_HARD_BREAK(target)
"\n" "\n"
end end
@ -331,7 +332,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
## ##
# Wraps +text+ to #width # Wraps +text+ to #width
def wrap text def wrap(text)
return unless text && !text.empty? return unless text && !text.empty?
text_len = @width - @indent text_len = @width - @indent

View file

@ -33,7 +33,7 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter
## ##
# Adds +document+ to the output, using its heading cutoff if present # Adds +document+ to the output, using its heading cutoff if present
def accept_document document def accept_document(document)
@omit_headings_below = document.omit_headings_below @omit_headings_below = document.omit_headings_below
super super
@ -42,7 +42,7 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter
## ##
# Adds +heading+ to the table of contents # Adds +heading+ to the table of contents
def accept_heading heading def accept_heading(heading)
@res << heading unless suppressed? heading @res << heading unless suppressed? heading
end end
@ -64,7 +64,7 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter
## ##
# Returns true if +heading+ is below the display threshold # Returns true if +heading+ is below the display threshold
def suppressed? heading def suppressed?(heading)
return false unless @omit_headings_below return false unless @omit_headings_below
heading.level > @omit_headings_below heading.level > @omit_headings_below

View file

@ -22,7 +22,7 @@ class RDoc::Markup::ToTest < RDoc::Markup::Formatter
@res << convert_flow(@am.flow(paragraph.text)) @res << convert_flow(@am.flow(paragraph.text))
end end
def accept_raw raw def accept_raw(raw)
@res << raw.parts.join @res << raw.parts.join
end end

View file

@ -18,7 +18,7 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
## ##
# Creates a new tt-only formatter. # Creates a new tt-only formatter.
def initialize markup = nil def initialize(markup = nil)
super nil, markup super nil, markup
add_tag :TT, nil, nil add_tag :TT, nil, nil
@ -27,28 +27,28 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
## ##
# Adds tts from +block_quote+ to the output # Adds tts from +block_quote+ to the output
def accept_block_quote block_quote def accept_block_quote(block_quote)
tt_sections block_quote.text tt_sections block_quote.text
end end
## ##
# Pops the list type for +list+ from #list_type # Pops the list type for +list+ from #list_type
def accept_list_end list def accept_list_end(list)
@list_type.pop @list_type.pop
end end
## ##
# Pushes the list type for +list+ onto #list_type # Pushes the list type for +list+ onto #list_type
def accept_list_start list def accept_list_start(list)
@list_type << list.type @list_type << list.type
end end
## ##
# Prepares the visitor for consuming +list_item+ # Prepares the visitor for consuming +list_item+
def accept_list_item_start list_item def accept_list_item_start(list_item)
case @list_type.last case @list_type.last
when :NOTE, :LABEL then when :NOTE, :LABEL then
Array(list_item.label).map do |label| Array(list_item.label).map do |label|
@ -60,7 +60,7 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
## ##
# Adds +paragraph+ to the output # Adds +paragraph+ to the output
def accept_paragraph paragraph def accept_paragraph(paragraph)
tt_sections(paragraph.text) tt_sections(paragraph.text)
end end
@ -68,7 +68,7 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
# Does nothing to +markup_item+ because it doesn't have any user-built # Does nothing to +markup_item+ because it doesn't have any user-built
# content # content
def do_nothing markup_item def do_nothing(markup_item)
end end
alias accept_blank_line do_nothing # :nodoc: alias accept_blank_line do_nothing # :nodoc:
@ -81,7 +81,7 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
## ##
# Extracts tt sections from +text+ # Extracts tt sections from +text+
def tt_sections text def tt_sections(text)
flow = @am.flow text.dup flow = @am.flow text.dup
flow.each do |item| flow.each do |item|

View file

@ -15,14 +15,14 @@ class RDoc::Markup::Verbatim < RDoc::Markup::Raw
@format = nil @format = nil
end end
def == other # :nodoc: def ==(other) # :nodoc:
super and @format == other.format super and @format == other.format
end end
## ##
# Calls #accept_verbatim on +visitor+ # Calls #accept_verbatim on +visitor+
def accept visitor def accept(visitor)
visitor.accept_verbatim self visitor.accept_verbatim self
end end
@ -50,7 +50,7 @@ class RDoc::Markup::Verbatim < RDoc::Markup::Raw
@parts = parts @parts = parts
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
self.class.name =~ /.*::(\w{1,4})/i self.class.name =~ /.*::(\w{1,4})/i
q.group 2, "[#{$1.downcase}: ", ']' do q.group 2, "[#{$1.downcase}: ", ']' do

View file

@ -355,18 +355,44 @@ class RDoc::Options
# +--[no-]embed-mixins+ (Default is +false+.) # +--[no-]embed-mixins+ (Default is +false+.)
attr_accessor :embed_mixins attr_accessor :embed_mixins
def initialize loaded_options = nil # :nodoc: ##
# Exclude the default patterns as well if true.
attr_reader :apply_default_exclude
##
# Words to be ignored in autolink cross-references
attr_accessor :autolink_excluded_words
##
# The prefix to use for class and module page paths
attr_accessor :class_module_path_prefix
##
# The prefix to use for file page paths
attr_accessor :file_path_prefix
##
# The preferred root URL for the documentation
attr_accessor :canonical_root
def initialize(loaded_options = nil) # :nodoc:
init_ivars init_ivars
override loaded_options if loaded_options override loaded_options if loaded_options
end end
DEFAULT_EXCLUDE = %w[
~\z \.orig\z \.rej\z \.bak\z
\.gemspec\z
]
def init_ivars # :nodoc: def init_ivars # :nodoc:
@autolink_excluded_words = []
@dry_run = false @dry_run = false
@embed_mixins = false @embed_mixins = false
@exclude = %w[ @exclude = []
~\z \.orig\z \.rej\z \.bak\z
\.gemspec\z
]
@files = nil @files = nil
@force_output = false @force_output = false
@force_update = true @force_update = true
@ -399,15 +425,19 @@ class RDoc::Options
@update_output_dir = true @update_output_dir = true
@verbosity = 1 @verbosity = 1
@visibility = :protected @visibility = :protected
@warn_missing_rdoc_ref = false @warn_missing_rdoc_ref = true
@webcvs = nil @webcvs = nil
@write_options = false @write_options = false
@encoding = Encoding::UTF_8 @encoding = Encoding::UTF_8
@charset = @encoding.name @charset = @encoding.name
@skip_tests = true @skip_tests = true
@apply_default_exclude = true
@class_module_path_prefix = nil
@file_path_prefix = nil
@canonical_root = nil
end end
def init_with map # :nodoc: def init_with(map) # :nodoc:
init_ivars init_ivars
encoding = map['encoding'] encoding = map['encoding']
@ -431,15 +461,18 @@ class RDoc::Options
@visibility = map['visibility'] @visibility = map['visibility']
@webcvs = map['webcvs'] @webcvs = map['webcvs']
@apply_default_exclude = map['apply_default_exclude']
@autolink_excluded_words = map['autolink_excluded_words']
@rdoc_include = sanitize_path map['rdoc_include'] @rdoc_include = sanitize_path map['rdoc_include']
@static_path = sanitize_path map['static_path'] @static_path = sanitize_path map['static_path']
end end
def yaml_initialize tag, map # :nodoc: def yaml_initialize(tag, map) # :nodoc:
init_with map init_with map
end end
def override map # :nodoc: def override(map) # :nodoc:
if map.has_key?('encoding') if map.has_key?('encoding')
encoding = map['encoding'] encoding = map['encoding']
@encoding = encoding ? Encoding.find(encoding) : encoding @encoding = encoding ? Encoding.find(encoding) : encoding
@ -463,6 +496,9 @@ class RDoc::Options
@title = map['title'] if map.has_key?('title') @title = map['title'] if map.has_key?('title')
@visibility = map['visibility'] if map.has_key?('visibility') @visibility = map['visibility'] if map.has_key?('visibility')
@webcvs = map['webcvs'] if map.has_key?('webcvs') @webcvs = map['webcvs'] if map.has_key?('webcvs')
@autolink_excluded_words = map['autolink_excluded_words'] if map.has_key?('autolink_excluded_words')
@apply_default_exclude = map['apply_default_exclude'] if map.has_key?('apply_default_exclude')
@canonical_root = map['canonical_root'] if map.has_key?('canonical_root')
@warn_missing_rdoc_ref = map['warn_missing_rdoc_ref'] if map.has_key?('warn_missing_rdoc_ref') @warn_missing_rdoc_ref = map['warn_missing_rdoc_ref'] if map.has_key?('warn_missing_rdoc_ref')
@ -474,7 +510,7 @@ class RDoc::Options
end end
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class === other and self.class === other and
@encoding == other.encoding and @encoding == other.encoding and
@embed_mixins == other.embed_mixins and @embed_mixins == other.embed_mixins and
@ -493,7 +529,9 @@ class RDoc::Options
@template == other.template and @template == other.template and
@title == other.title and @title == other.title and
@visibility == other.visibility and @visibility == other.visibility and
@webcvs == other.webcvs @webcvs == other.webcvs and
@apply_default_exclude == other.apply_default_exclude and
@autolink_excluded_words == other.autolink_excluded_words
end end
## ##
@ -564,10 +602,12 @@ class RDoc::Options
if @exclude.nil? or Regexp === @exclude then if @exclude.nil? or Regexp === @exclude then
# done, #finish is being re-run # done, #finish is being re-run
@exclude @exclude
elsif @exclude.empty? then elsif !@apply_default_exclude and @exclude.empty? then
nil nil
else else
Regexp.new(@exclude.join("|")) exclude = @exclude
exclude |= DEFAULT_EXCLUDE if @apply_default_exclude
Regexp.new(exclude.join("|"))
end end
end end
@ -662,7 +702,7 @@ class RDoc::Options
## ##
# Parses command line options. # Parses command line options.
def parse argv def parse(argv)
ignore_invalid = true ignore_invalid = true
argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT'] argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT']
@ -801,6 +841,11 @@ Usage: #{opt.program_name} [options] [names...]
@exclude << value @exclude << value
end end
opt.on("--[no-]apply-default-exclude",
"Use default PATTERN to exclude.") do |value|
@apply_default_exclude = value
end
opt.separator nil opt.separator nil
opt.on("--no-skipping-tests", nil, opt.on("--no-skipping-tests", nil,
@ -972,6 +1017,13 @@ Usage: #{opt.program_name} [options] [names...]
opt.separator nil opt.separator nil
opt.on("--autolink-excluded-words=WORDS", Array,
"Words to be ignored in autolink cross-references") do |value|
@autolink_excluded_words.concat value
end
opt.separator nil
opt.on("--hyperlink-all", "-A", opt.on("--hyperlink-all", "-A",
"Generate hyperlinks for all words that", "Generate hyperlinks for all words that",
"correspond to known methods, even if they", "correspond to known methods, even if they",
@ -1229,14 +1281,14 @@ Usage: #{opt.program_name} [options] [names...]
## ##
# Set quietness to +bool+ # Set quietness to +bool+
def quiet= bool def quiet=(bool)
@verbosity = bool ? 0 : 1 @verbosity = bool ? 0 : 1
end end
## ##
# Removes directories from +path+ that are outside the current directory # Removes directories from +path+ that are outside the current directory
def sanitize_path path def sanitize_path(path)
require 'pathname' require 'pathname'
dot = Pathname.new('.').expand_path dot = Pathname.new('.').expand_path
@ -1263,7 +1315,7 @@ Usage: #{opt.program_name} [options] [names...]
# the options instance. This allows generators to add custom options or set # the options instance. This allows generators to add custom options or set
# default options. # default options.
def setup_generator generator_name = @generator_name def setup_generator(generator_name = @generator_name)
@generator = @generators[generator_name] @generator = @generators[generator_name]
unless @generator then unless @generator then
@ -1285,7 +1337,7 @@ Usage: #{opt.program_name} [options] [names...]
## ##
# Finds the template dir for +template+ # Finds the template dir for +template+
def template_dir_for template def template_dir_for(template)
template_path = File.join 'rdoc', 'generator', 'template', template template_path = File.join 'rdoc', 'generator', 'template', template
$LOAD_PATH.map do |path| $LOAD_PATH.map do |path|
@ -1302,7 +1354,7 @@ Usage: #{opt.program_name} [options] [names...]
# When +:all+ is passed, visibility is set to +:private+, similarly to # When +:all+ is passed, visibility is set to +:private+, similarly to
# RDOCOPT="--all", see #visibility for more information. # RDOCOPT="--all", see #visibility for more information.
def visibility= visibility def visibility=(visibility)
case visibility case visibility
when :all when :all
@visibility = :private @visibility = :private
@ -1314,7 +1366,7 @@ Usage: #{opt.program_name} [options] [names...]
## ##
# Displays a warning using Kernel#warn if we're being verbose # Displays a warning using Kernel#warn if we're being verbose
def warn message def warn(message)
super message if @verbosity > 1 super message if @verbosity > 1
end end

View file

@ -91,7 +91,7 @@ class RDoc::Parser
# Checks if +file+ is a zip file in disguise. Signatures from # Checks if +file+ is a zip file in disguise. Signatures from
# http://www.garykessler.net/library/file_sigs.html # http://www.garykessler.net/library/file_sigs.html
def self.zip? file def self.zip?(file)
zip_signature = File.read file, 4 zip_signature = File.read file, 4
zip_signature == "PK\x03\x04" or zip_signature == "PK\x03\x04" or
@ -104,7 +104,7 @@ class RDoc::Parser
## ##
# Return a parser that can handle a particular extension # Return a parser that can handle a particular extension
def self.can_parse file_name def self.can_parse(file_name)
parser = can_parse_by_name file_name parser = can_parse_by_name file_name
# HACK Selenium hides a jar file using a .txt extension # HACK Selenium hides a jar file using a .txt extension
@ -117,7 +117,7 @@ class RDoc::Parser
# Returns a parser that can handle the extension for +file_name+. This does # Returns a parser that can handle the extension for +file_name+. This does
# not depend upon the file being readable. # not depend upon the file being readable.
def self.can_parse_by_name file_name def self.can_parse_by_name(file_name)
_, parser = RDoc::Parser.parsers.find { |regexp,| regexp =~ file_name } _, parser = RDoc::Parser.parsers.find { |regexp,| regexp =~ file_name }
# The default parser must not parse binary files # The default parser must not parse binary files
@ -140,7 +140,7 @@ class RDoc::Parser
## ##
# Returns the file type from the modeline in +file_name+ # Returns the file type from the modeline in +file_name+
def self.check_modeline file_name def self.check_modeline(file_name)
line = File.open file_name do |io| line = File.open file_name do |io|
io.gets io.gets
end end
@ -166,7 +166,7 @@ class RDoc::Parser
# Finds and instantiates the correct parser for the given +file_name+ and # Finds and instantiates the correct parser for the given +file_name+ and
# +content+. # +content+.
def self.for top_level, content, options, stats def self.for(top_level, content, options, stats)
file_name = top_level.absolute_name file_name = top_level.absolute_name
return if binary? file_name return if binary? file_name
@ -191,7 +191,7 @@ class RDoc::Parser
content = remove_modeline content content = remove_modeline content
parser.new top_level, file_name, content, options, stats parser.new top_level, content, options, stats
rescue SystemCallError rescue SystemCallError
nil nil
end end
@ -208,7 +208,7 @@ class RDoc::Parser
## ##
# Removes an emacs-style modeline from the first line of the document # Removes an emacs-style modeline from the first line of the document
def self.remove_modeline content def self.remove_modeline(content)
content.sub(/\A.*-\*-\s*(.*?\S)\s*-\*-.*\r?\n/, '') content.sub(/\A.*-\*-\s*(.*?\S)\s*-\*-.*\r?\n/, '')
end end
@ -229,7 +229,7 @@ class RDoc::Parser
# #
# Any comment style may be used to hide the markup comment. # Any comment style may be used to hide the markup comment.
def self.use_markup content def self.use_markup(content)
markup = content.lines.first(3).grep(/markup:\s+(\w+)/) { $1 }.first markup = content.lines.first(3).grep(/markup:\s+(\w+)/) { $1 }.first
return unless markup return unless markup
@ -252,12 +252,12 @@ class RDoc::Parser
# RDoc::Markup::PreProcess object is created which allows processing of # RDoc::Markup::PreProcess object is created which allows processing of
# directives. # directives.
def initialize top_level, file_name, content, options, stats def initialize(top_level, content, options, stats)
@top_level = top_level @top_level = top_level
@top_level.parser = self.class @top_level.parser = self.class
@store = @top_level.store @store = @top_level.store
@file_name = file_name @file_name = top_level.absolute_name
@content = content @content = content
@options = options @options = options
@stats = stats @stats = stats

View file

@ -168,7 +168,7 @@ class RDoc::Parser::C < RDoc::Parser
# Prepares for parsing a C file. See RDoc::Parser#initialize for details on # Prepares for parsing a C file. See RDoc::Parser#initialize for details on
# the arguments. # the arguments.
def initialize top_level, file_name, content, options, stats def initialize(top_level, content, options, stats)
super super
@known_classes = RDoc::KNOWN_CLASSES.dup @known_classes = RDoc::KNOWN_CLASSES.dup
@ -193,7 +193,7 @@ class RDoc::Parser::C < RDoc::Parser
@enclosure_dependencies.extend TSort @enclosure_dependencies.extend TSort
def @enclosure_dependencies.tsort_each_node &block def @enclosure_dependencies.tsort_each_node(&block)
each_key(&block) each_key(&block)
rescue TSort::Cyclic => e rescue TSort::Cyclic => e
cycle_vars = e.message.scan(/"(.*?)"/).flatten cycle_vars = e.message.scan(/"(.*?)"/).flatten
@ -211,7 +211,7 @@ class RDoc::Parser::C < RDoc::Parser
retry retry
end end
def @enclosure_dependencies.tsort_each_child node, &block def @enclosure_dependencies.tsort_each_child(node, &block)
fetch(node, []).each(&block) fetch(node, []).each(&block)
end end
end end
@ -248,9 +248,7 @@ class RDoc::Parser::C < RDoc::Parser
# method that reference the same function. # method that reference the same function.
def add_alias(var_name, class_obj, old_name, new_name, comment) def add_alias(var_name, class_obj, old_name, new_name, comment)
al = RDoc::Alias.new '', old_name, new_name, '' al = RDoc::Alias.new '', old_name, new_name, comment, singleton: @singleton_classes.key?(var_name)
al.singleton = @singleton_classes.key? var_name
al.comment = comment
al.record_location @top_level al.record_location @top_level
class_obj.add_alias al class_obj.add_alias al
@stats.add_alias al @stats.add_alias al
@ -521,7 +519,7 @@ class RDoc::Parser::C < RDoc::Parser
# Finds the comment for an alias on +class_name+ from +new_name+ to # Finds the comment for an alias on +class_name+ from +new_name+ to
# +old_name+ # +old_name+
def find_alias_comment class_name, new_name, old_name def find_alias_comment(class_name, new_name, old_name)
content =~ %r%((?>/\*.*?\*/\s+)) content =~ %r%((?>/\*.*?\*/\s+))
rb_define_alias\(\s*#{Regexp.escape class_name}\s*, rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
\s*"#{Regexp.escape new_name}"\s*, \s*"#{Regexp.escape new_name}"\s*,
@ -539,7 +537,7 @@ class RDoc::Parser::C < RDoc::Parser
# +read+ and +write+ are the read/write flags ('1' or '0'). Either both or # +read+ and +write+ are the read/write flags ('1' or '0'). Either both or
# neither must be provided. # neither must be provided.
def find_attr_comment var_name, attr_name, read = nil, write = nil def find_attr_comment(var_name, attr_name, read = nil, write = nil)
attr_name = Regexp.escape attr_name attr_name = Regexp.escape attr_name
rw = if read and write then rw = if read and write then
@ -572,7 +570,7 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Generate a Ruby-method table # Generate a Ruby-method table
def gen_body_table file_content def gen_body_table(file_content)
table = {} table = {}
file_content.scan(%r{ file_content.scan(%r{
((?>/\*.*?\*/\s*)?) ((?>/\*.*?\*/\s*)?)
@ -596,7 +594,7 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Find the C code corresponding to a Ruby method # Find the C code corresponding to a Ruby method
def find_body class_name, meth_name, meth_obj, file_content, quiet = false def find_body(class_name, meth_name, meth_obj, file_content, quiet = false)
if file_content if file_content
@body_table ||= {} @body_table ||= {}
@body_table[file_content] ||= gen_body_table file_content @body_table[file_content] ||= gen_body_table file_content
@ -721,7 +719,7 @@ class RDoc::Parser::C < RDoc::Parser
# */ # */
# VALUE cFoo = rb_define_class("Foo", rb_cObject); # VALUE cFoo = rb_define_class("Foo", rb_cObject);
def find_class_comment class_name, class_mod def find_class_comment(class_name, class_mod)
comment = nil comment = nil
if @content =~ %r% if @content =~ %r%
@ -754,7 +752,7 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Generate a const table # Generate a const table
def gen_const_table file_content def gen_const_table(file_content)
table = {} table = {}
@content.scan(%r{ @content.scan(%r{
(?<doc>(?>^\s*/\*.*?\*/\s+)) (?<doc>(?>^\s*/\*.*?\*/\s+))
@ -808,9 +806,9 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Handles modifiers in +comment+ and updates +meth_obj+ as appropriate. # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
def find_modifiers comment, meth_obj def find_modifiers(comment, meth_obj)
comment.normalize comment.normalize
comment.extract_call_seq meth_obj meth_obj.call_seq = comment.extract_call_seq
look_for_directives_in meth_obj, comment look_for_directives_in meth_obj, comment
end end
@ -818,7 +816,7 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+ # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
def find_override_comment class_name, meth_obj def find_override_comment(class_name, meth_obj)
name = Regexp.escape meth_obj.name name = Regexp.escape meth_obj.name
prefix = Regexp.escape meth_obj.name_prefix prefix = Regexp.escape meth_obj.name_prefix
@ -1015,10 +1013,9 @@ class RDoc::Parser::C < RDoc::Parser
type = 'method' # force public type = 'method' # force public
end end
meth_obj = RDoc::AnyMethod.new '', meth_name singleton = singleton || %w[singleton_method module_function].include?(type)
meth_obj = RDoc::AnyMethod.new '', meth_name, singleton: singleton
meth_obj.c_function = function meth_obj.c_function = function
meth_obj.singleton =
singleton || %w[singleton_method module_function].include?(type)
p_count = Integer(param_count) rescue -1 p_count = Integer(param_count) rescue -1
@ -1063,7 +1060,7 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Registers a singleton class +sclass_var+ as a singleton of +class_var+ # Registers a singleton class +sclass_var+ as a singleton of +class_var+
def handle_singleton sclass_var, class_var def handle_singleton(sclass_var, class_var)
class_name = @known_classes[class_var] class_name = @known_classes[class_var]
@known_classes[sclass_var] = class_name @known_classes[sclass_var] = class_name
@ -1074,7 +1071,7 @@ class RDoc::Parser::C < RDoc::Parser
# Loads the variable map with the given +name+ from the RDoc::Store, if # Loads the variable map with the given +name+ from the RDoc::Store, if
# present. # present.
def load_variable_map map_name def load_variable_map(map_name)
return {} unless files = @store.cache[map_name] return {} unless files = @store.cache[map_name]
return {} unless name_map = files[@file_name] return {} unless name_map = files[@file_name]
@ -1104,7 +1101,7 @@ class RDoc::Parser::C < RDoc::Parser
# This method modifies the +comment+ # This method modifies the +comment+
# Both :main: and :title: directives are deprecated and will be removed in RDoc 7. # Both :main: and :title: directives are deprecated and will be removed in RDoc 7.
def look_for_directives_in context, comment def look_for_directives_in(context, comment)
@preprocess.handle comment, context do |directive, param| @preprocess.handle comment, context do |directive, param|
case directive case directive
when 'main' then when 'main' then
@ -1141,7 +1138,7 @@ class RDoc::Parser::C < RDoc::Parser
# Extracts parameters from the +method_body+ and returns a method # Extracts parameters from the +method_body+ and returns a method
# parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT # parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT
def rb_scan_args method_body def rb_scan_args(method_body)
method_body =~ /rb_scan_args\((.*?)\)/m method_body =~ /rb_scan_args\((.*?)\)/m
return '(*args)' unless $1 return '(*args)' unless $1
@ -1252,7 +1249,7 @@ class RDoc::Parser::C < RDoc::Parser
## ##
# Creates a RDoc::Comment instance. # Creates a RDoc::Comment instance.
def new_comment text = nil, location = nil, language = nil def new_comment(text = nil, location = nil, language = nil)
RDoc::Comment.new(text, location, language).tap do |comment| RDoc::Comment.new(text, location, language).tap do |comment|
comment.format = @markup comment.format = @markup
end end

View file

@ -23,7 +23,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
# Continued function listings are joined together as a single entry. # Continued function listings are joined together as a single entry.
# Continued descriptions are joined to make a single paragraph. # Continued descriptions are joined to make a single paragraph.
def continue_entry_body entry_body, continuation def continue_entry_body(entry_body, continuation)
return unless last = entry_body.last return unless last = entry_body.last
if last =~ /\)\s*\z/ and continuation =~ /\A\(/ then if last =~ /\)\s*\z/ and continuation =~ /\A\(/ then
@ -41,7 +41,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
## ##
# Creates an RDoc::Markup::Document given the +groups+ of ChangeLog entries. # Creates an RDoc::Markup::Document given the +groups+ of ChangeLog entries.
def create_document groups def create_document(groups)
doc = RDoc::Markup::Document.new doc = RDoc::Markup::Document.new
doc.omit_headings_below = 2 doc.omit_headings_below = 2
doc.file = @top_level doc.file = @top_level
@ -63,7 +63,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
# Returns a list of ChangeLog entries an RDoc::Markup nodes for the given # Returns a list of ChangeLog entries an RDoc::Markup nodes for the given
# +entries+. # +entries+.
def create_entries entries def create_entries(entries)
out = [] out = []
entries.each do |entry, items| entries.each do |entry, items|
@ -80,7 +80,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
# Returns an RDoc::Markup::List containing the given +items+ in the # Returns an RDoc::Markup::List containing the given +items+ in the
# ChangeLog # ChangeLog
def create_items items def create_items(items)
list = RDoc::Markup::List.new :NOTE list = RDoc::Markup::List.new :NOTE
items.each do |item| items.each do |item|
@ -100,7 +100,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
## ##
# Groups +entries+ by date. # Groups +entries+ by date.
def group_entries entries def group_entries(entries)
@time_cache ||= {} @time_cache ||= {}
entries.group_by do |title, _| entries.group_by do |title, _|
begin begin
@ -210,8 +210,9 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
grouped_entries = group_entries entries grouped_entries = group_entries entries
doc = create_document grouped_entries doc = create_document grouped_entries
comment = RDoc::Comment.new(@content)
@top_level.comment = doc comment.document = doc
@top_level.comment = comment
@top_level @top_level
end end
@ -259,7 +260,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
# RDoc::Parser::ChangeLog::Git::LogEntry list for the given # RDoc::Parser::ChangeLog::Git::LogEntry list for the given
# +entries+. # +entries+.
def create_entries entries def create_entries(entries)
# git log entries have no strictly itemized style like the old # git log entries have no strictly itemized style like the old
# style, just assume Markdown. # style, just assume Markdown.
entries.map do |commit, entry| entries.map do |commit, entry|
@ -295,7 +296,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
"label-#{commit}" "label-#{commit}"
end end
def label context = nil def label(context = nil)
aref aref
end end
@ -310,7 +311,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
end + " {#{author}}[mailto:#{email}]" end + " {#{author}}[mailto:#{email}]"
end end
def accept visitor def accept(visitor)
visitor.accept_heading self visitor.accept_heading self
begin begin
if visitor.respond_to?(:code_object=) if visitor.respond_to?(:code_object=)
@ -327,7 +328,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
end end
end end
def pretty_print q # :nodoc: def pretty_print(q) # :nodoc:
q.group(2, '[log_entry: ', ']') do q.group(2, '[log_entry: ', ']') do
q.text commit q.text commit
q.text ',' q.text ','

View file

@ -18,7 +18,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
attr_accessor :visibility attr_accessor :visibility
attr_reader :container, :singleton attr_reader :container, :singleton
def initialize(top_level, file_name, content, options, stats) def initialize(top_level, content, options, stats)
super super
content = handle_tab_width(content) content = handle_tab_width(content)
@ -31,10 +31,21 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
@track_visibility = :nodoc != @options.visibility @track_visibility = :nodoc != @options.visibility
@encoding = @options.encoding @encoding = @options.encoding
@module_nesting = [top_level] @module_nesting = [[top_level, false]]
@container = top_level @container = top_level
@visibility = :public @visibility = :public
@singleton = false @singleton = false
@in_proc_block = false
end
# Suppress `extend` and `include` within block
# because they might be a metaprogramming block
# example: `Module.new { include M }` `M.module_eval { include N }`
def with_in_proc_block
@in_proc_block = true
yield
@in_proc_block = false
end end
# Dive into another container # Dive into another container
@ -43,28 +54,30 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
old_container = @container old_container = @container
old_visibility = @visibility old_visibility = @visibility
old_singleton = @singleton old_singleton = @singleton
old_in_proc_block = @in_proc_block
@visibility = :public @visibility = :public
@container = container @container = container
@singleton = singleton @singleton = singleton
@in_proc_block = false
unless singleton unless singleton
@module_nesting.push container
# Need to update module parent chain to emulate Module.nesting. # Need to update module parent chain to emulate Module.nesting.
# This mechanism is inaccurate and needs to be fixed. # This mechanism is inaccurate and needs to be fixed.
container.parent = old_container container.parent = old_container
end end
@module_nesting.push([container, singleton])
yield container yield container
ensure ensure
@container = old_container @container = old_container
@visibility = old_visibility @visibility = old_visibility
@singleton = old_singleton @singleton = old_singleton
@module_nesting.pop unless singleton @in_proc_block = old_in_proc_block
@module_nesting.pop
end end
# Records the location of this +container+ in the file for this parser and # Records the location of this +container+ in the file for this parser and
# adds it to the list of classes and modules in the file. # adds it to the list of classes and modules in the file.
def record_location container # :nodoc: def record_location(container) # :nodoc:
case container case container
when RDoc::ClassModule then when RDoc::ClassModule then
@top_level.add_to_classes_or_modules container @top_level.add_to_classes_or_modules container
@ -204,6 +217,10 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
@stats.add_method meth @stats.add_method meth
end end
def has_modifier_nodoc?(line_no) # :nodoc:
@modifier_comments[line_no]&.text&.match?(/\A#\s*:nodoc:/)
end
def handle_modifier_directive(code_object, line_no) # :nodoc: def handle_modifier_directive(code_object, line_no) # :nodoc:
comment = @modifier_comments[line_no] comment = @modifier_comments[line_no]
@preprocess.handle(comment.text, code_object) if comment @preprocess.handle(comment.text, code_object) if comment
@ -272,21 +289,19 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
if attributes if attributes
attributes.each do |attr| attributes.each do |attr|
a = RDoc::Attr.new(@container, attr, rw, processed_comment) a = RDoc::Attr.new(@container, attr, rw, processed_comment, singleton: @singleton)
a.store = @store a.store = @store
a.line = line_no a.line = line_no
a.singleton = @singleton
record_location(a) record_location(a)
@container.add_attribute(a) @container.add_attribute(a)
a.visibility = visibility a.visibility = visibility
end end
elsif line_no || node elsif line_no || node
method_name ||= call_node_name_arguments(node).first if is_call_node method_name ||= call_node_name_arguments(node).first if is_call_node
meth = RDoc::AnyMethod.new(@container, method_name) meth = RDoc::AnyMethod.new(@container, method_name, singleton: @singleton || singleton_method)
meth.singleton = @singleton || singleton_method
handle_consecutive_comment_directive(meth, comment) handle_consecutive_comment_directive(meth, comment)
comment.normalize comment.normalize
comment.extract_call_seq(meth) meth.call_seq = comment.extract_call_seq
meth.comment = comment meth.comment = comment
if node if node
tokens = visible_tokens_from_location(node.location) tokens = visible_tokens_from_location(node.location)
@ -299,7 +314,6 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
meth, meth,
line_no: line_no, line_no: line_no,
visibility: visibility, visibility: visibility,
singleton: @singleton || singleton_method,
params: '()', params: '()',
calls_super: false, calls_super: false,
block_params: nil, block_params: nil,
@ -435,8 +449,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
comment = consecutive_comment(line_no) comment = consecutive_comment(line_no)
handle_consecutive_comment_directive(@container, comment) handle_consecutive_comment_directive(@container, comment)
visibility = @container.find_method(old_name, @singleton)&.visibility || :public visibility = @container.find_method(old_name, @singleton)&.visibility || :public
a = RDoc::Alias.new(nil, old_name, new_name, comment, @singleton) a = RDoc::Alias.new(nil, old_name, new_name, comment, singleton: @singleton)
a.comment = comment
handle_modifier_directive(a, line_no) handle_modifier_directive(a, line_no)
a.store = @store a.store = @store
a.line = line_no a.line = line_no
@ -455,10 +468,9 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
return unless @container.document_children return unless @container.document_children
names.each do |symbol| names.each do |symbol|
a = RDoc::Attr.new(nil, symbol.to_s, rw, comment) a = RDoc::Attr.new(nil, symbol.to_s, rw, comment, singleton: @singleton)
a.store = @store a.store = @store
a.line = line_no a.line = line_no
a.singleton = @singleton
record_location(a) record_location(a)
handle_modifier_directive(a, line_no) handle_modifier_directive(a, line_no)
@container.add_attribute(a) if should_document?(a) @container.add_attribute(a) if should_document?(a)
@ -467,6 +479,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
end end
def add_includes_extends(names, rdoc_class, line_no) # :nodoc: def add_includes_extends(names, rdoc_class, line_no) # :nodoc:
return if @in_proc_block
comment = consecutive_comment(line_no) comment = consecutive_comment(line_no)
handle_consecutive_comment_directive(@container, comment) handle_consecutive_comment_directive(@container, comment)
names.each do |name| names.each do |name|
@ -492,51 +505,53 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
# Adds a method defined by `def` syntax # Adds a method defined by `def` syntax
def add_method(name, receiver_name:, receiver_fallback_type:, visibility:, singleton:, params:, calls_super:, block_params:, tokens:, start_line:, end_line:) def add_method(name, receiver_name:, receiver_fallback_type:, visibility:, singleton:, params:, calls_super:, block_params:, tokens:, start_line:, args_end_line:, end_line:)
return if @in_proc_block
receiver = receiver_name ? find_or_create_module_path(receiver_name, receiver_fallback_type) : @container receiver = receiver_name ? find_or_create_module_path(receiver_name, receiver_fallback_type) : @container
meth = RDoc::AnyMethod.new(nil, name) meth = RDoc::AnyMethod.new(nil, name, singleton: singleton)
if (comment = consecutive_comment(start_line)) if (comment = consecutive_comment(start_line))
handle_consecutive_comment_directive(@container, comment) handle_consecutive_comment_directive(@container, comment)
handle_consecutive_comment_directive(meth, comment) handle_consecutive_comment_directive(meth, comment)
comment.normalize comment.normalize
comment.extract_call_seq(meth) meth.call_seq = comment.extract_call_seq
meth.comment = comment meth.comment = comment
end end
handle_modifier_directive(meth, start_line) handle_modifier_directive(meth, start_line)
handle_modifier_directive(meth, args_end_line)
handle_modifier_directive(meth, end_line) handle_modifier_directive(meth, end_line)
return unless should_document?(meth) return unless should_document?(meth)
if meth.name == 'initialize' && !singleton
if meth.dont_rename_initialize
visibility = :protected
else
meth.name = 'new'
singleton = true
visibility = :public
end
end
internal_add_method( internal_add_method(
receiver, receiver,
meth, meth,
line_no: start_line, line_no: start_line,
visibility: visibility, visibility: visibility,
singleton: singleton,
params: params, params: params,
calls_super: calls_super, calls_super: calls_super,
block_params: block_params, block_params: block_params,
tokens: tokens tokens: tokens
) )
# Rename after add_method to register duplicated 'new' and 'initialize'
# defined in c and ruby just like the old parser did.
if meth.name == 'initialize' && !singleton
if meth.dont_rename_initialize
meth.visibility = :protected
else
meth.name = 'new'
meth.singleton = true
meth.visibility = :public
end
end
end end
private def internal_add_method(container, meth, line_no:, visibility:, singleton:, params:, calls_super:, block_params:, tokens:) # :nodoc: private def internal_add_method(container, meth, line_no:, visibility:, params:, calls_super:, block_params:, tokens:) # :nodoc:
meth.name ||= meth.call_seq[/\A[^()\s]+/] if meth.call_seq meth.name ||= meth.call_seq[/\A[^()\s]+/] if meth.call_seq
meth.name ||= 'unknown' meth.name ||= 'unknown'
meth.store = @store meth.store = @store
meth.line = line_no meth.line = line_no
meth.singleton = singleton
container.add_method(meth) # should add after setting singleton and before setting visibility container.add_method(meth) # should add after setting singleton and before setting visibility
meth.visibility = visibility meth.visibility = visibility
meth.params ||= params meth.params ||= params
@ -565,12 +580,17 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
if root_name.empty? if root_name.empty?
mod = @top_level mod = @top_level
else else
@module_nesting.reverse_each do |nesting| @module_nesting.reverse_each do |nesting, singleton|
next if singleton
mod = nesting.find_module_named(root_name) mod = nesting.find_module_named(root_name)
break if mod break if mod
# If a constant is found and it is not a module or class, RDoc can't document about it.
# Return an anonymous module to avoid wrong document creation.
return RDoc::NormalModule.new(nil) if nesting.find_constant_named(root_name)
end end
return mod || add_module.call(@top_level, root_name, create_mode) unless name last_nesting, = @module_nesting.reverse_each.find { |_, singleton| !singleton }
mod ||= add_module.call(@top_level, root_name, :module) return mod || add_module.call(last_nesting, root_name, create_mode) unless name
mod ||= add_module.call(last_nesting, root_name, :module)
end end
path.each do |name| path.each do |name|
mod = mod.find_module_named(name) || add_module.call(mod, name, :module) mod = mod.find_module_named(name) || add_module.call(mod, name, :module)
@ -584,7 +604,8 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
owner_name, path = constant_path.split('::', 2) owner_name, path = constant_path.split('::', 2)
return constant_path if owner_name.empty? # ::Foo, ::Foo::Bar return constant_path if owner_name.empty? # ::Foo, ::Foo::Bar
mod = nil mod = nil
@module_nesting.reverse_each do |nesting| @module_nesting.reverse_each do |nesting, singleton|
next if singleton
mod = nesting.find_module_named(owner_name) mod = nesting.find_module_named(owner_name)
break if mod break if mod
end end
@ -598,7 +619,10 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
def find_or_create_constant_owner_name(constant_path) def find_or_create_constant_owner_name(constant_path)
const_path, colon, name = constant_path.rpartition('::') const_path, colon, name = constant_path.rpartition('::')
if colon.empty? # class Foo if colon.empty? # class Foo
[@container, name] # Within `class C` or `module C`, owner is C(== current container)
# Within `class <<C`, owner is C.singleton_class
# but RDoc don't track constants of a singleton class of module
[(@singleton ? nil : @container), name]
elsif const_path.empty? # class ::Foo elsif const_path.empty? # class ::Foo
[@top_level, name] [@top_level, name]
else # `class Foo::Bar` or `class ::Foo::Bar` else # `class Foo::Bar` or `class ::Foo::Bar`
@ -612,6 +636,8 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
comment = consecutive_comment(start_line) comment = consecutive_comment(start_line)
handle_consecutive_comment_directive(@container, comment) handle_consecutive_comment_directive(@container, comment)
owner, name = find_or_create_constant_owner_name(constant_name) owner, name = find_or_create_constant_owner_name(constant_name)
return unless owner
constant = RDoc::Constant.new(name, rhs_name, comment) constant = RDoc::Constant.new(name, rhs_name, comment)
constant.store = @store constant.store = @store
constant.line = start_line constant.line = start_line
@ -635,24 +661,29 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
# Adds module or class # Adds module or class
def add_module_or_class(module_name, start_line, end_line, is_class: false, superclass_name: nil) def add_module_or_class(module_name, start_line, end_line, is_class: false, superclass_name: nil, superclass_expr: nil)
comment = consecutive_comment(start_line) comment = consecutive_comment(start_line)
handle_consecutive_comment_directive(@container, comment) handle_consecutive_comment_directive(@container, comment)
return unless @container.document_children return unless @container.document_children
owner, name = find_or_create_constant_owner_name(module_name) owner, name = find_or_create_constant_owner_name(module_name)
if is_class return unless owner
mod = owner.classes_hash[name] || owner.add_class(RDoc::NormalClass, name, superclass_name || '::Object')
if is_class
# RDoc::NormalClass resolves superclass name despite of the lack of module nesting information. # RDoc::NormalClass resolves superclass name despite of the lack of module nesting information.
# We need to fix it when RDoc::NormalClass resolved to a wrong constant name # We need to fix it when RDoc::NormalClass resolved to a wrong constant name
if superclass_name if superclass_name
superclass_full_path = resolve_constant_path(superclass_name) superclass_full_path = resolve_constant_path(superclass_name)
superclass = @store.find_class_or_module(superclass_full_path) if superclass_full_path superclass = @store.find_class_or_module(superclass_full_path) if superclass_full_path
superclass_full_path ||= superclass_name superclass_full_path ||= superclass_name
superclass_full_path = superclass_full_path.sub(/^::/, '')
end
# add_class should be done after resolving superclass
mod = owner.classes_hash[name] || owner.add_class(RDoc::NormalClass, name, superclass_name || superclass_expr || '::Object')
if superclass_name
if superclass if superclass
mod.superclass = superclass mod.superclass = superclass
elsif mod.superclass.is_a?(String) && mod.superclass != superclass_full_path elsif (mod.superclass.is_a?(String) || mod.superclass.name == 'Object') && mod.superclass != superclass_full_path
mod.superclass = superclass_full_path mod.superclass = superclass_full_path
end end
end end
@ -676,6 +707,20 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
@store = store @store = store
end end
def visit_if_node(node)
if node.end_keyword
super
else
# Visit with the order in text representation to handle this method comment
# # comment
# def f
# end if call_node
node.statements.accept(self)
node.predicate.accept(self)
end
end
alias visit_unless_node visit_if_node
def visit_call_node(node) def visit_call_node(node)
@scanner.process_comments_until(node.location.start_line - 1) @scanner.process_comments_until(node.location.start_line - 1)
if node.receiver.nil? if node.receiver.nil?
@ -713,6 +758,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
when :private_class_method when :private_class_method
_visit_call_public_private_class_method(node, :private) { super } _visit_call_public_private_class_method(node, :private) { super }
else else
node.arguments&.accept(self)
super super
end end
else else
@ -720,6 +766,13 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
end end
end end
def visit_block_node(node)
@scanner.with_in_proc_block do
# include, extend and method definition inside block are not documentable
super
end
end
def visit_alias_method_node(node) def visit_alias_method_node(node)
@scanner.process_comments_until(node.location.start_line - 1) @scanner.process_comments_until(node.location.start_line - 1)
return unless node.old_name.is_a?(Prism::SymbolNode) && node.new_name.is_a?(Prism::SymbolNode) return unless node.old_name.is_a?(Prism::SymbolNode) && node.new_name.is_a?(Prism::SymbolNode)
@ -727,12 +780,13 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
end end
def visit_module_node(node) def visit_module_node(node)
node.constant_path.accept(self)
@scanner.process_comments_until(node.location.start_line - 1) @scanner.process_comments_until(node.location.start_line - 1)
module_name = constant_path_string(node.constant_path) module_name = constant_path_string(node.constant_path)
mod = @scanner.add_module_or_class(module_name, node.location.start_line, node.location.end_line) if module_name mod = @scanner.add_module_or_class(module_name, node.location.start_line, node.location.end_line) if module_name
if mod if mod
@scanner.with_container(mod) do @scanner.with_container(mod) do
super node.body&.accept(self)
@scanner.process_comments_until(node.location.end_line) @scanner.process_comments_until(node.location.end_line)
end end
else else
@ -741,13 +795,16 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
end end
def visit_class_node(node) def visit_class_node(node)
node.constant_path.accept(self)
node.superclass&.accept(self)
@scanner.process_comments_until(node.location.start_line - 1) @scanner.process_comments_until(node.location.start_line - 1)
superclass_name = constant_path_string(node.superclass) if node.superclass superclass_name = constant_path_string(node.superclass) if node.superclass
superclass_expr = node.superclass.slice if node.superclass && !superclass_name
class_name = constant_path_string(node.constant_path) class_name = constant_path_string(node.constant_path)
klass = @scanner.add_module_or_class(class_name, node.location.start_line, node.location.end_line, is_class: true, superclass_name: superclass_name) if class_name klass = @scanner.add_module_or_class(class_name, node.location.start_line, node.location.end_line, is_class: true, superclass_name: superclass_name, superclass_expr: superclass_expr) if class_name
if klass if klass
@scanner.with_container(klass) do @scanner.with_container(klass) do
super node.body&.accept(self)
@scanner.process_comments_until(node.location.end_line) @scanner.process_comments_until(node.location.end_line)
end end
else else
@ -758,6 +815,12 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
def visit_singleton_class_node(node) def visit_singleton_class_node(node)
@scanner.process_comments_until(node.location.start_line - 1) @scanner.process_comments_until(node.location.start_line - 1)
if @scanner.has_modifier_nodoc?(node.location.start_line)
# Skip visiting inside the singleton class. Also skips creation of node.expression as a module
@scanner.skip_comments_until(node.location.end_line)
return
end
expression = node.expression expression = node.expression
expression = expression.body.body.first if expression.is_a?(Prism::ParenthesesNode) && expression.body&.body&.size == 1 expression = expression.body.body.first if expression.is_a?(Prism::ParenthesesNode) && expression.body&.body&.size == 1
@ -772,9 +835,10 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
when Prism::SelfNode when Prism::SelfNode
mod = @scanner.container if @scanner.container != @top_level mod = @scanner.container if @scanner.container != @top_level
end end
expression.accept(self)
if mod if mod
@scanner.with_container(mod, singleton: true) do @scanner.with_container(mod, singleton: true) do
super node.body&.accept(self)
@scanner.process_comments_until(node.location.end_line) @scanner.process_comments_until(node.location.end_line)
end end
else else
@ -784,6 +848,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
def visit_def_node(node) def visit_def_node(node)
start_line = node.location.start_line start_line = node.location.start_line
args_end_line = node.parameters&.location&.end_line || start_line
end_line = node.location.end_line end_line = node.location.end_line
@scanner.process_comments_until(start_line - 1) @scanner.process_comments_until(start_line - 1)
@ -834,6 +899,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
calls_super: calls_super, calls_super: calls_super,
tokens: tokens, tokens: tokens,
start_line: start_line, start_line: start_line,
args_end_line: args_end_line,
end_line: end_line end_line: end_line
) )
ensure ensure
@ -942,7 +1008,7 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
@scanner.visibility = visibility @scanner.visibility = visibility
else # `public :foo, :bar`, `private def foo; end` else # `public :foo, :bar`, `private def foo; end`
yield yield
names = visibility_method_arguments(call_node, singleton: @scanner.singleton) names = visibility_method_arguments(call_node, singleton: false)
@scanner.change_method_visibility(names, visibility) if names @scanner.change_method_visibility(names, visibility) if names
end end
end end

View file

@ -170,7 +170,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Creates a new Ruby parser. # Creates a new Ruby parser.
def initialize(top_level, file_name, content, options, stats) def initialize(top_level, content, options, stats)
super super
content = handle_tab_width(content) content = handle_tab_width(content)
@ -200,7 +200,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Retrieves the read token stream and replaces +pattern+ with +replacement+ # Retrieves the read token stream and replaces +pattern+ with +replacement+
# using gsub. If the result is only a ";" returns an empty string. # using gsub. If the result is only a ";" returns an empty string.
def get_tkread_clean pattern, replacement # :nodoc: def get_tkread_clean(pattern, replacement) # :nodoc:
read = get_tkread.gsub(pattern, replacement).strip read = get_tkread.gsub(pattern, replacement).strip
return '' if read == ';' return '' if read == ';'
read read
@ -214,7 +214,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# +singleton+ if the methods following should be converted to singleton # +singleton+ if the methods following should be converted to singleton
# methods. # methods.
def get_visibility_information tk, single # :nodoc: def get_visibility_information(tk, single) # :nodoc:
vis_type = tk[:text] vis_type = tk[:text]
singleton = single == SINGLE singleton = single == SINGLE
@ -292,8 +292,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Creates a new attribute in +container+ with +name+. # Creates a new attribute in +container+ with +name+.
def create_attr container, single, name, rw, comment # :nodoc: def create_attr(container, single, name, rw, comment) # :nodoc:
att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE att = RDoc::Attr.new get_tkread, name, rw, comment, singleton: single == SINGLE
record_location att record_location att
container.add_attribute att container.add_attribute att
@ -306,7 +306,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Creates a module alias in +container+ at +rhs_name+ (or at the top-level # Creates a module alias in +container+ at +rhs_name+ (or at the top-level
# for "::") with the name from +constant+. # for "::") with the name from +constant+.
def create_module_alias container, constant, rhs_name # :nodoc: def create_module_alias(container, constant, rhs_name) # :nodoc:
mod = if rhs_name =~ /^::/ then mod = if rhs_name =~ /^::/ then
@store.find_class_or_module rhs_name @store.find_class_or_module rhs_name
else else
@ -346,7 +346,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# with :: separated named) and return the ultimate name, the associated # with :: separated named) and return the ultimate name, the associated
# container, and the given name (with the ::). # container, and the given name (with the ::).
def get_class_or_module container, ignore_constants = false def get_class_or_module(container, ignore_constants = false)
skip_tkspace skip_tkspace
name_t = get_tk name_t = get_tk
given_name = ''.dup given_name = ''.dup
@ -564,7 +564,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# We see the RPAREN as the next token, so we need to exit early. This still # We see the RPAREN as the next token, so we need to exit early. This still
# won't catch all cases (such as "a = yield + 1" # won't catch all cases (such as "a = yield + 1"
def get_end_token tk # :nodoc: def get_end_token(tk) # :nodoc:
case tk[:kind] case tk[:kind]
when :on_lparen when :on_lparen
token = RDoc::Parser::RipperStateLex::Token.new token = RDoc::Parser::RipperStateLex::Token.new
@ -584,7 +584,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Retrieves the method container for a singleton method. # Retrieves the method container for a singleton method.
def get_method_container container, name_t # :nodoc: def get_method_container(container, name_t) # :nodoc:
prev_container = container prev_container = container
container = container.find_module_named(name_t[:text]) container = container.find_module_named(name_t[:text])
@ -652,7 +652,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Marks containers between +container+ and +ancestor+ as ignored # Marks containers between +container+ and +ancestor+ as ignored
def suppress_parents container, ancestor # :nodoc: def suppress_parents(container, ancestor) # :nodoc:
while container and container != ancestor do while container and container != ancestor do
container.suppress unless container.documented? container.suppress unless container.documented?
container = container.parent container = container.parent
@ -667,7 +667,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# #
# This routine modifies its +comment+ parameter. # This routine modifies its +comment+ parameter.
def look_for_directives_in container, comment def look_for_directives_in(container, comment)
@preprocess.handle comment, container do |directive, param| @preprocess.handle comment, container do |directive, param|
case directive case directive
when 'method', 'singleton-method', when 'method', 'singleton-method',
@ -687,7 +687,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Adds useful info about the parser to +message+ # Adds useful info about the parser to +message+
def make_message message def make_message(message)
prefix = "#{@file_name}:".dup prefix = "#{@file_name}:".dup
tk = peek_tk tk = peek_tk
@ -699,7 +699,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Creates a comment with the correct format # Creates a comment with the correct format
def new_comment comment, line_no = nil def new_comment(comment, line_no = nil)
c = RDoc::Comment.new comment, @top_level, :ruby c = RDoc::Comment.new comment, @top_level, :ruby
c.line = line_no c.line = line_no
c.format = @markup c.format = @markup
@ -792,8 +792,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
return return
end end
al = RDoc::Alias.new(get_tkread, old_name, new_name, comment, al = RDoc::Alias.new(get_tkread, old_name, new_name, comment, singleton: single == SINGLE)
single == SINGLE)
record_location al record_location al
al.line = line_no al.line = line_no
@ -852,7 +851,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses a class in +context+ with +comment+ # Parses a class in +context+ with +comment+
def parse_class container, single, tk, comment def parse_class(container, single, tk, comment)
line_no = tk[:line_no] line_no = tk[:line_no]
declaration_context = container declaration_context = container
@ -886,8 +885,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses and creates a regular class # Parses and creates a regular class
def parse_class_regular container, declaration_context, single, # :nodoc: def parse_class_regular(container, declaration_context, single, # :nodoc:
name_t, given_name, comment name_t, given_name, comment)
superclass = '::Object' superclass = '::Object'
if given_name =~ /^::/ then if given_name =~ /^::/ then
@ -926,7 +925,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parses a singleton class in +container+ with the given +name+ and # Parses a singleton class in +container+ with the given +name+ and
# +comment+. # +comment+.
def parse_class_singleton container, name, comment # :nodoc: def parse_class_singleton(container, name, comment) # :nodoc:
other = @store.find_class_named name other = @store.find_class_named name
unless other then unless other then
@ -965,7 +964,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parses a constant in +context+ with +comment+. If +ignore_constants+ is # Parses a constant in +context+ with +comment+. If +ignore_constants+ is
# true, no found constants will be added to RDoc. # true, no found constants will be added to RDoc.
def parse_constant container, tk, comment, ignore_constants = false def parse_constant(container, tk, comment, ignore_constants = false)
line_no = tk[:line_no] line_no = tk[:line_no]
name = tk[:text] name = tk[:text]
@ -1032,7 +1031,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
true true
end end
def parse_constant_body container, constant, is_array_or_hash # :nodoc: def parse_constant_body(container, constant, is_array_or_hash) # :nodoc:
nest = 0 nest = 0
rhs_name = ''.dup rhs_name = ''.dup
@ -1091,7 +1090,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Generates an RDoc::Method or RDoc::Attr from +comment+ by looking for # Generates an RDoc::Method or RDoc::Attr from +comment+ by looking for
# :method: or :attr: directives in +comment+. # :method: or :attr: directives in +comment+.
def parse_comment container, tk, comment def parse_comment(container, tk, comment)
return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc' return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc'
column = tk[:char_no] column = tk[:char_no]
line_no = comment.line.nil? ? tk[:line_no] : comment.line line_no = comment.line.nil? ? tk[:line_no] : comment.line
@ -1119,7 +1118,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parse a comment that is describing an attribute in +container+ with the # Parse a comment that is describing an attribute in +container+ with the
# given +name+ and +comment+. # given +name+ and +comment+.
def parse_comment_attr container, type, name, comment # :nodoc: def parse_comment_attr(container, type, name, comment) # :nodoc:
return if name.empty? return if name.empty?
rw = case type rw = case type
@ -1131,8 +1130,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
create_attr container, NORMAL, name, rw, comment create_attr container, NORMAL, name, rw, comment
end end
def parse_comment_ghost container, text, name, column, line_no, # :nodoc: def parse_comment_ghost(container, text, name, column, line_no, # :nodoc:
comment comment)
name = nil if name.empty? name = nil if name.empty?
meth = RDoc::GhostMethod.new get_tkread, name meth = RDoc::GhostMethod.new get_tkread, name
@ -1153,7 +1152,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
end end
comment.normalize comment.normalize
comment.extract_call_seq meth meth.call_seq = comment.extract_call_seq
return unless meth.name return unless meth.name
@ -1170,7 +1169,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Creates an RDoc::Method on +container+ from +comment+ if there is a # Creates an RDoc::Method on +container+ from +comment+ if there is a
# Signature section in the comment # Signature section in the comment
def parse_comment_tomdoc container, tk, comment def parse_comment_tomdoc(container, tk, comment)
return unless signature = RDoc::TomDoc.signature(comment) return unless signature = RDoc::TomDoc.signature(comment)
column = tk[:char_no] column = tk[:char_no]
line_no = tk[:line_no] line_no = tk[:line_no]
@ -1205,7 +1204,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parses an +include+ or +extend+, indicated by the +klass+ and adds it to # Parses an +include+ or +extend+, indicated by the +klass+ and adds it to
# +container+ # with +comment+ # +container+ # with +comment+
def parse_extend_or_include klass, container, comment # :nodoc: def parse_extend_or_include(klass, container, comment) # :nodoc:
loop do loop do
skip_tkspace_comment skip_tkspace_comment
@ -1225,7 +1224,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses an +included+ with a block feature of ActiveSupport::Concern. # Parses an +included+ with a block feature of ActiveSupport::Concern.
def parse_included_with_activesupport_concern container, comment # :nodoc: def parse_included_with_activesupport_concern(container, comment) # :nodoc:
skip_tkspace_without_nl skip_tkspace_without_nl
tk = get_tk tk = get_tk
unless tk[:kind] == :on_lbracket || (tk[:kind] == :on_kw && tk[:text] == 'do') unless tk[:kind] == :on_lbracket || (tk[:kind] == :on_kw && tk[:text] == 'do')
@ -1243,7 +1242,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# #
# Returns true if the comment was not consumed. # Returns true if the comment was not consumed.
def parse_identifier container, single, tk, comment # :nodoc: def parse_identifier(container, single, tk, comment) # :nodoc:
case tk[:text] case tk[:text]
when 'private', 'protected', 'public', 'private_class_method', when 'private', 'protected', 'public', 'private_class_method',
'public_class_method', 'module_function' then 'public_class_method', 'module_function' then
@ -1358,10 +1357,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
return unless name return unless name
meth = RDoc::MetaMethod.new get_tkread, name meth = RDoc::MetaMethod.new get_tkread, name, singleton: singleton
record_location meth record_location meth
meth.line = line_no meth.line = line_no
meth.singleton = singleton
remove_token_listener self remove_token_listener self
@ -1387,7 +1385,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# determine the name while +tk+ is used in an error message if the name # determine the name while +tk+ is used in an error message if the name
# cannot be determined. # cannot be determined.
def parse_meta_method_name comment, tk # :nodoc: def parse_meta_method_name(comment, tk) # :nodoc:
if comment.text.sub!(/^# +:?method: *(\S*).*?\n/i, '') then if comment.text.sub!(/^# +:?method: *(\S*).*?\n/i, '') then
return $1 unless $1.empty? return $1 unless $1.empty?
end end
@ -1411,13 +1409,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses the parameters and block for a meta-programmed method. # Parses the parameters and block for a meta-programmed method.
def parse_meta_method_params container, single, meth, tk, comment # :nodoc: def parse_meta_method_params(container, single, meth, tk, comment) # :nodoc:
token_listener meth do token_listener meth do
meth.params = '' meth.params = ''
look_for_directives_in meth, comment look_for_directives_in meth, comment
comment.normalize comment.normalize
comment.extract_call_seq meth meth.call_seq = comment.extract_call_seq
container.add_method meth container.add_method meth
@ -1461,9 +1459,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
return unless name return unless name
meth = RDoc::AnyMethod.new get_tkread, name meth = RDoc::AnyMethod.new get_tkread, name, singleton: single == SINGLE ? true : singleton
look_for_directives_in meth, comment look_for_directives_in meth, comment
meth.singleton = single == SINGLE ? true : singleton
if singleton if singleton
# `current_line_visibility' is useless because it works against # `current_line_visibility' is useless because it works against
# the normal method named as same as the singleton method, after # the normal method named as same as the singleton method, after
@ -1485,7 +1482,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
parse_method_params_and_body container, single, meth, added_container parse_method_params_and_body container, single, meth, added_container
comment.normalize comment.normalize
comment.extract_call_seq meth meth.call_seq = comment.extract_call_seq
meth.comment = comment meth.comment = comment
@ -1498,7 +1495,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses the parameters and body of +meth+ # Parses the parameters and body of +meth+
def parse_method_params_and_body container, single, meth, added_container def parse_method_params_and_body(container, single, meth, added_container)
token_listener meth do token_listener meth do
parse_method_parameters meth parse_method_parameters meth
@ -1528,7 +1525,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses a method that needs to be ignored. # Parses a method that needs to be ignored.
def parse_method_dummy container def parse_method_dummy(container)
dummy = RDoc::Context.new dummy = RDoc::Context.new
dummy.parent = container dummy.parent = container
dummy.store = container.store dummy.store = container.store
@ -1541,7 +1538,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Returns the method name, the container it is in (for def Foo.name) and if # Returns the method name, the container it is in (for def Foo.name) and if
# it is a singleton or regular method. # it is a singleton or regular method.
def parse_method_name container # :nodoc: def parse_method_name(container) # :nodoc:
skip_tkspace skip_tkspace
name_t = get_tk name_t = get_tk
back_tk = skip_tkspace_without_nl back_tk = skip_tkspace_without_nl
@ -1568,7 +1565,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# For the given +container+ and initial name token +name_t+ the method name # For the given +container+ and initial name token +name_t+ the method name
# is parsed from the token stream for a regular method. # is parsed from the token stream for a regular method.
def parse_method_name_regular container, name_t # :nodoc: def parse_method_name_regular(container, name_t) # :nodoc:
if :on_op == name_t[:kind] && (%w{* & [] []= <<}.include?(name_t[:text])) then if :on_op == name_t[:kind] && (%w{* & [] []= <<}.include?(name_t[:text])) then
name_t[:text] name_t[:text]
else else
@ -1586,7 +1583,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# and the new +container+ (if necessary) are parsed from the token stream # and the new +container+ (if necessary) are parsed from the token stream
# for a singleton method. # for a singleton method.
def parse_method_name_singleton container, name_t # :nodoc: def parse_method_name_singleton(container, name_t) # :nodoc:
skip_tkspace skip_tkspace
name_t2 = get_tk name_t2 = get_tk
@ -1697,7 +1694,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# #
# and add this as the block_params for the method # and add this as the block_params for the method
def parse_method_parameters method def parse_method_parameters(method)
res = parse_method_or_yield_parameters method res = parse_method_or_yield_parameters method
res = "(#{res})" unless res =~ /\A\(/ res = "(#{res})" unless res =~ /\A\(/
@ -1712,7 +1709,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses an RDoc::NormalModule in +container+ with +comment+ # Parses an RDoc::NormalModule in +container+ with +comment+
def parse_module container, single, tk, comment def parse_module(container, single, tk, comment)
container, name_t, = get_class_or_module container container, name_t, = get_class_or_module container
name = name_t[:text] name = name_t[:text]
@ -1992,7 +1989,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parses up to +no+ symbol arguments surrounded by () and places them in # Parses up to +no+ symbol arguments surrounded by () and places them in
# +args+. # +args+.
def parse_symbol_arg_paren no # :nodoc: def parse_symbol_arg_paren(no) # :nodoc:
args = [] args = []
loop do loop do
@ -2020,7 +2017,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parses up to +no+ symbol arguments separated by spaces and places them in # Parses up to +no+ symbol arguments separated by spaces and places them in
# +args+. # +args+.
def parse_symbol_arg_space no, tk # :nodoc: def parse_symbol_arg_space(no, tk) # :nodoc:
args = [] args = []
unget_tk tk unget_tk tk
@ -2068,7 +2065,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Parses statements in the top-level +container+ # Parses statements in the top-level +container+
def parse_top_level_statements container def parse_top_level_statements(container)
comment = collect_first_comment comment = collect_first_comment
look_for_directives_in container, comment look_for_directives_in container, comment
@ -2146,7 +2143,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# the name is in +allowed+. A directive can be found anywhere up to the end # the name is in +allowed+. A directive can be found anywhere up to the end
# of the current line. # of the current line.
def read_directive allowed def read_directive(allowed)
tokens = [] tokens = []
while tk = get_tk do while tk = get_tk do
@ -2178,7 +2175,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# #
# See also RDoc::Markup::PreProcess#handle_directive # See also RDoc::Markup::PreProcess#handle_directive
def read_documentation_modifiers context, allowed def read_documentation_modifiers(context, allowed)
skip_tkspace_without_nl skip_tkspace_without_nl
directive, value = read_directive allowed directive, value = read_directive allowed
@ -2197,7 +2194,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Records the location of this +container+ in the file for this parser and # Records the location of this +container+ in the file for this parser and
# adds it to the list of classes and modules in the file. # adds it to the list of classes and modules in the file.
def record_location container # :nodoc: def record_location(container) # :nodoc:
case container case container
when RDoc::ClassModule then when RDoc::ClassModule then
@top_level.add_to_classes_or_modules container @top_level.add_to_classes_or_modules container
@ -2308,7 +2305,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Skips the next method in +container+ # Skips the next method in +container+
def skip_method container def skip_method(container)
meth = RDoc::AnyMethod.new "", "anon" meth = RDoc::AnyMethod.new "", "anon"
parse_method_parameters meth parse_method_parameters meth
parse_statements container, false, meth parse_statements container, false, meth
@ -2329,7 +2326,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Updates visibility in +container+ from +vis_type+ and +vis+. # Updates visibility in +container+ from +vis_type+ and +vis+.
def update_visibility container, vis_type, vis, singleton # :nodoc: def update_visibility(container, vis_type, vis, singleton) # :nodoc:
new_methods = [] new_methods = []
case vis_type case vis_type
@ -2374,7 +2371,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
## ##
# Prints +message+ to +$stderr+ unless we're being quiet # Prints +message+ to +$stderr+ unless we're being quiet
def warn message def warn(message)
@options.warn make_message message @options.warn make_message message
end end

View file

@ -14,7 +14,7 @@ class RDoc::Parser::Simple < RDoc::Parser
## ##
# Prepare to parse a plain file # Prepare to parse a plain file
def initialize(top_level, file_name, content, options, stats) def initialize(top_level, content, options, stats)
super super
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
@ -38,7 +38,7 @@ class RDoc::Parser::Simple < RDoc::Parser
## ##
# Removes the encoding magic comment from +text+ # Removes the encoding magic comment from +text+
def remove_coding_comment text def remove_coding_comment(text)
text.sub(/\A# .*coding[=:].*$/, '') text.sub(/\A# .*coding[=:].*$/, '')
end end
@ -49,7 +49,7 @@ class RDoc::Parser::Simple < RDoc::Parser
# dashes at the beginning of the line. Three or more dashes are considered # dashes at the beginning of the line. Three or more dashes are considered
# to be a rule and ignored. # to be a rule and ignored.
def remove_private_comment comment def remove_private_comment(comment)
# Workaround for gsub encoding for Ruby 1.9.2 and earlier # Workaround for gsub encoding for Ruby 1.9.2 and earlier
empty = '' empty = ''
empty = RDoc::Encoding.change_encoding empty, comment.encoding empty = RDoc::Encoding.change_encoding empty, comment.encoding

View file

@ -75,7 +75,7 @@ class RDoc::RD
# Parses +rd+ source and returns an RDoc::Markup::Document. If the # Parses +rd+ source and returns an RDoc::Markup::Document. If the
# <tt>=begin</tt> or <tt>=end</tt> lines are missing they will be added. # <tt>=begin</tt> or <tt>=end</tt> lines are missing they will be added.
def self.parse rd def self.parse(rd)
rd = rd.lines.to_a rd = rd.lines.to_a
if rd.find { |i| /\S/ === i } and !rd.find{|i| /^=begin\b/ === i } then if rd.find { |i| /\S/ === i } and !rd.find{|i| /^=begin\b/ === i } then

1
lib/rdoc/rd/.document Normal file
View file

@ -0,0 +1 @@
inline.rb

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
# #
# DO NOT MODIFY!!!! # DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.8.1 # This file is automatically generated by Racc 1.8.0
# from Racc grammar file "block_parser.ry". # from Racc grammar file "block_parser.ry".
# #
@ -23,7 +23,7 @@ unless $".find {|p| p.end_with?('/racc/info.rb')}
$".push "#{__dir__}/racc/info.rb" $".push "#{__dir__}/racc/info.rb"
module Racc module Racc
VERSION = '1.8.1' VERSION = '1.8.0'
Version = VERSION Version = VERSION
Copyright = 'Copyright (c) 1999-2006 Minero Aoki' Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
end end
@ -38,7 +38,7 @@ unless defined?(::ParseError)
ParseError = Racc::ParseError # :nodoc: ParseError = Racc::ParseError # :nodoc:
end end
# Racc is an LALR(1) parser generator. # Racc is a LALR(1) parser generator.
# It is written in Ruby itself, and generates Ruby programs. # It is written in Ruby itself, and generates Ruby programs.
# #
# == Command-line Reference # == Command-line Reference

View file

@ -20,7 +20,7 @@ class RDoc::RD::Inline
# +rdoc+ may be another Inline or a String. If +reference+ is not given it # +rdoc+ may be another Inline or a String. If +reference+ is not given it
# will use the text from +rdoc+. # will use the text from +rdoc+.
def self.new rdoc, reference = rdoc def self.new(rdoc, reference = rdoc)
if self === rdoc and reference.equal? rdoc then if self === rdoc and reference.equal? rdoc then
rdoc rdoc
else else
@ -31,7 +31,7 @@ class RDoc::RD::Inline
## ##
# Initializes the Inline with +rdoc+ and +inline+ # Initializes the Inline with +rdoc+ and +inline+
def initialize rdoc, reference # :not-new: def initialize(rdoc, reference) # :not-new:
@reference = reference.equal?(rdoc) ? reference.dup : reference @reference = reference.equal?(rdoc) ? reference.dup : reference
# unpack # unpack
@ -39,7 +39,7 @@ class RDoc::RD::Inline
@rdoc = rdoc @rdoc = rdoc
end end
def == other # :nodoc: def ==(other) # :nodoc:
self.class === other and self.class === other and
@reference == other.reference and @rdoc == other.rdoc @reference == other.reference and @rdoc == other.rdoc
end end
@ -47,7 +47,7 @@ class RDoc::RD::Inline
## ##
# Appends +more+ to this inline. +more+ may be a String or another Inline. # Appends +more+ to this inline. +more+ may be a String or another Inline.
def append more def append(more)
case more case more
when String then when String then
@reference += more @reference += more

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
# #
# DO NOT MODIFY!!!! # DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.8.1 # This file is automatically generated by Racc 1.8.0
# from Racc grammar file "inline_parser.ry". # from Racc grammar file "inline_parser.ry".
# #
@ -23,7 +23,7 @@ unless $".find {|p| p.end_with?('/racc/info.rb')}
$".push "#{__dir__}/racc/info.rb" $".push "#{__dir__}/racc/info.rb"
module Racc module Racc
VERSION = '1.8.1' VERSION = '1.8.0'
Version = VERSION Version = VERSION
Copyright = 'Copyright (c) 1999-2006 Minero Aoki' Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
end end
@ -38,7 +38,7 @@ unless defined?(::ParseError)
ParseError = Racc::ParseError # :nodoc: ParseError = Racc::ParseError # :nodoc:
end end
# Racc is an LALR(1) parser generator. # Racc is a LALR(1) parser generator.
# It is written in Ruby itself, and generates Ruby programs. # It is written in Ruby itself, and generates Ruby programs.
# #
# == Command-line Reference # == Command-line Reference

View file

@ -64,4 +64,5 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat
s.required_rubygems_version = Gem::Requirement.new(">= 2.2") s.required_rubygems_version = Gem::Requirement.new(">= 2.2")
s.add_dependency 'psych', '>= 4.0.0' s.add_dependency 'psych', '>= 4.0.0'
s.add_dependency 'erb'
end end

View file

@ -69,7 +69,7 @@ class RDoc::RDoc
## ##
# The current documentation store # The current documentation store
attr_reader :store attr_accessor :store
## ##
# Add +klass+ that can generate output after parsing # Add +klass+ that can generate output after parsing
@ -89,7 +89,7 @@ class RDoc::RDoc
## ##
# Sets the active RDoc::RDoc instance # Sets the active RDoc::RDoc instance
def self.current= rdoc def self.current=(rdoc)
@current = rdoc @current = rdoc
end end
@ -118,7 +118,7 @@ class RDoc::RDoc
# Gathers a set of parseable files from the files and directories listed in # Gathers a set of parseable files from the files and directories listed in
# +files+. # +files+.
def gather_files files def gather_files(files)
files = [@options.root.to_s] if files.empty? files = [@options.root.to_s] if files.empty?
file_list = normalized_file_list files, true, @options.exclude file_list = normalized_file_list files, true, @options.exclude
@ -208,15 +208,6 @@ option)
last last
end end
##
# Sets the current documentation tree to +store+ and sets the store's rdoc
# driver to this instance.
def store= store
@store = store
@store.rdoc = self
end
## ##
# Update the flag file in an output directory. # Update the flag file in an output directory.
@ -246,7 +237,7 @@ option)
# representing candidates for documentation. It may also contain comments # representing candidates for documentation. It may also contain comments
# (starting with '#') # (starting with '#')
def parse_dot_doc_file in_dir, filename def parse_dot_doc_file(in_dir, filename)
# read and strip comments # read and strip comments
patterns = File.read(filename).gsub(/#.*/, '') patterns = File.read(filename).gsub(/#.*/, '')
@ -320,7 +311,7 @@ option)
# files. However we may well contain subdirectories which must be tested # files. However we may well contain subdirectories which must be tested
# for .document files. # for .document files.
def list_files_in_directory dir def list_files_in_directory(dir)
files = Dir.glob File.join(dir, "*") files = Dir.glob File.join(dir, "*")
normalized_file_list files, false, @options.exclude normalized_file_list files, false, @options.exclude
@ -329,7 +320,7 @@ option)
## ##
# Parses +filename+ and returns an RDoc::TopLevel # Parses +filename+ and returns an RDoc::TopLevel
def parse_file filename def parse_file(filename)
encoding = @options.encoding encoding = @options.encoding
filename = filename.encode encoding filename = filename.encode encoding
@ -400,7 +391,7 @@ The internal error was:
## ##
# Parse each file on the command line, recursively entering directories. # Parse each file on the command line, recursively entering directories.
def parse_files files def parse_files(files)
file_list = gather_files files file_list = gather_files files
@stats = RDoc::Stats.new @store, file_list.length, @options.verbosity @stats = RDoc::Stats.new @store, file_list.length, @options.verbosity
@ -427,7 +418,7 @@ The internal error was:
# Removes file extensions known to be unparseable from +files+ and TAGS # Removes file extensions known to be unparseable from +files+ and TAGS
# files for emacs and vim. # files for emacs and vim.
def remove_unparseable files def remove_unparseable(files)
files.reject do |file, *| files.reject do |file, *|
file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or
(file =~ /tags$/i and (file =~ /tags$/i and
@ -449,9 +440,7 @@ The internal error was:
# By default, output will be stored in a directory called "doc" below the # By default, output will be stored in a directory called "doc" below the
# current directory, so make sure you're somewhere writable before invoking. # current directory, so make sure you're somewhere writable before invoking.
def document options def document(options)
self.store = RDoc::Store.new
if RDoc::Options === options then if RDoc::Options === options then
@options = options @options = options
else else
@ -460,6 +449,8 @@ The internal error was:
end end
@options.finish @options.finish
@store = RDoc::Store.new(@options)
if @options.pipe then if @options.pipe then
handle_pipe handle_pipe
exit exit
@ -469,12 +460,6 @@ The internal error was:
@last_modified = setup_output_dir @options.op_dir, @options.force_update @last_modified = setup_output_dir @options.op_dir, @options.force_update
end end
@store.encoding = @options.encoding
@store.dry_run = @options.dry_run
@store.main = @options.main_page
@store.title = @options.title
@store.path = @options.op_dir
@start_time = Time.now @start_time = Time.now
@store.load_cache @store.load_cache

View file

@ -96,7 +96,7 @@ class RDoc::RI::Driver
## ##
# Dump +data_path+ using pp # Dump +data_path+ using pp
def self.dump data_path def self.dump(data_path)
require 'pp' require 'pp'
File.open data_path, 'rb' do |io| File.open data_path, 'rb' do |io|
@ -107,7 +107,7 @@ class RDoc::RI::Driver
## ##
# Parses +argv+ and returns a Hash of options # Parses +argv+ and returns a Hash of options
def self.process_args argv def self.process_args(argv)
options = default_options options = default_options
opts = OptionParser.new do |opt| opts = OptionParser.new do |opt|
@ -384,7 +384,7 @@ or the PAGER environment variable.
## ##
# Runs the ri command line executable using +argv+ # Runs the ri command line executable using +argv+
def self.run argv = ARGV def self.run(argv = ARGV)
options = process_args argv options = process_args argv
if options[:dump_path] then if options[:dump_path] then
@ -399,7 +399,7 @@ or the PAGER environment variable.
## ##
# Creates a new driver using +initial_options+ from ::process_args # Creates a new driver using +initial_options+ from ::process_args
def initialize initial_options = {} def initialize(initial_options = {})
@paging = false @paging = false
@classes = nil @classes = nil
@ -420,7 +420,7 @@ or the PAGER environment variable.
*options[:extra_doc_dirs]) do |path, type| *options[:extra_doc_dirs]) do |path, type|
@doc_dirs << path @doc_dirs << path
store = RDoc::RI::Store.new path, type store = RDoc::RI::Store.new(RDoc::Options.new, path: path, type: type)
store.load_cache store.load_cache
@stores << store @stores << store
end end
@ -438,7 +438,7 @@ or the PAGER environment variable.
## ##
# Adds paths for undocumented classes +also_in+ to +out+ # Adds paths for undocumented classes +also_in+ to +out+
def add_also_in out, also_in def add_also_in(out, also_in)
return if also_in.empty? return if also_in.empty?
out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Rule.new(1)
@ -455,7 +455,7 @@ or the PAGER environment variable.
# Adds a class header to +out+ for class +name+ which is described in # Adds a class header to +out+ for class +name+ which is described in
# +classes+. # +classes+.
def add_class out, name, classes def add_class(out, name, classes)
heading = if classes.all? { |klass| klass.module? } then heading = if classes.all? { |klass| klass.module? } then
name name
else else
@ -475,14 +475,14 @@ or the PAGER environment variable.
## ##
# Adds "(from ...)" to +out+ for +store+ # Adds "(from ...)" to +out+ for +store+
def add_from out, store def add_from(out, store)
out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
end end
## ##
# Adds +extends+ to +out+ # Adds +extends+ to +out+
def add_extends out, extends def add_extends(out, extends)
add_extension_modules out, 'Extended by', extends add_extension_modules out, 'Extended by', extends
end end
@ -490,7 +490,7 @@ or the PAGER environment variable.
# Adds a list of +extensions+ to this module of the given +type+ to +out+. # Adds a list of +extensions+ to this module of the given +type+ to +out+.
# add_includes and add_extends call this, so you should use those directly. # add_includes and add_extends call this, so you should use those directly.
def add_extension_modules out, type, extensions def add_extension_modules(out, type, extensions)
return if extensions.empty? return if extensions.empty?
out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Rule.new(1)
@ -508,7 +508,7 @@ or the PAGER environment variable.
## ##
# Renders multiple included +modules+ from +store+ to +out+. # Renders multiple included +modules+ from +store+ to +out+.
def add_extension_modules_multiple out, store, modules # :nodoc: def add_extension_modules_multiple(out, store, modules) # :nodoc:
out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
wout, with = modules.partition { |incl| incl.comment.empty? } wout, with = modules.partition { |incl| incl.comment.empty? }
@ -518,7 +518,7 @@ or the PAGER environment variable.
with.each do |incl| with.each do |incl|
out << RDoc::Markup::Paragraph.new(incl.name) out << RDoc::Markup::Paragraph.new(incl.name)
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << incl.comment out << incl.comment.parse
end end
unless wout.empty? then unless wout.empty? then
@ -535,28 +535,28 @@ or the PAGER environment variable.
## ##
# Adds a single extension module +include+ from +store+ to +out+ # Adds a single extension module +include+ from +store+ to +out+
def add_extension_modules_single out, store, include # :nodoc: def add_extension_modules_single(out, store, include) # :nodoc:
name = include.name name = include.name
path = store.friendly_path path = store.friendly_path
out << RDoc::Markup::Paragraph.new("#{name} (from #{path})") out << RDoc::Markup::Paragraph.new("#{name} (from #{path})")
if include.comment then if include.comment then
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << include.comment out << include.comment.parse
end end
end end
## ##
# Adds +includes+ to +out+ # Adds +includes+ to +out+
def add_includes out, includes def add_includes(out, includes)
add_extension_modules out, 'Includes', includes add_extension_modules out, 'Includes', includes
end end
## ##
# Looks up the method +name+ and adds it to +out+ # Looks up the method +name+ and adds it to +out+
def add_method out, name def add_method(out, name)
filtered = lookup_method name filtered = lookup_method name
method_document out, name, filtered method_document out, name, filtered
end end
@ -564,7 +564,7 @@ or the PAGER environment variable.
## ##
# Adds documentation for all methods in +klass+ to +out+ # Adds documentation for all methods in +klass+ to +out+
def add_method_documentation out, klass def add_method_documentation(out, klass)
klass.method_list.each do |method| klass.method_list.each do |method|
begin begin
add_method out, method.full_name add_method out, method.full_name
@ -577,7 +577,7 @@ or the PAGER environment variable.
## ##
# Adds a list of +methods+ to +out+ with a heading of +name+ # Adds a list of +methods+ to +out+ with a heading of +name+
def add_method_list out, methods, name def add_method_list(out, methods, name)
return if methods.empty? return if methods.empty?
out << RDoc::Markup::Heading.new(1, "#{name}:") out << RDoc::Markup::Heading.new(1, "#{name}:")
@ -597,7 +597,7 @@ or the PAGER environment variable.
## ##
# Returns ancestor classes of +klass+ # Returns ancestor classes of +klass+
def ancestors_of klass def ancestors_of(klass)
ancestors = [] ancestors = []
unexamined = [klass] unexamined = [klass]
@ -634,7 +634,7 @@ or the PAGER environment variable.
## ##
# Builds a RDoc::Markup::Document from +found+, +klasess+ and +includes+ # Builds a RDoc::Markup::Document from +found+, +klasess+ and +includes+
def class_document name, found, klasses, includes, extends def class_document(name, found, klasses, includes, extends)
also_in = [] also_in = []
out = RDoc::Markup::Document.new out = RDoc::Markup::Document.new
@ -657,12 +657,12 @@ or the PAGER environment variable.
## ##
# Adds the class +comment+ to +out+. # Adds the class +comment+ to +out+.
def class_document_comment out, comment # :nodoc: def class_document_comment(out, document) # :nodoc:
unless comment.empty? then unless document.empty? then
out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Rule.new(1)
if comment.merged? then if document.merged? then
parts = comment.parts parts = document.parts
parts = parts.zip [RDoc::Markup::BlankLine.new] * parts.length parts = parts.zip [RDoc::Markup::BlankLine.new] * parts.length
parts.flatten! parts.flatten!
parts.pop parts.pop
@ -677,7 +677,7 @@ or the PAGER environment variable.
## ##
# Adds the constants from +klass+ to the Document +out+. # Adds the constants from +klass+ to the Document +out+.
def class_document_constants out, klass # :nodoc: def class_document_constants(out, klass) # :nodoc:
return if klass.constants.empty? return if klass.constants.empty?
out << RDoc::Markup::Heading.new(1, "Constants:") out << RDoc::Markup::Heading.new(1, "Constants:")
@ -687,7 +687,7 @@ or the PAGER environment variable.
constants = klass.constants.sort_by { |constant| constant.name } constants = klass.constants.sort_by { |constant| constant.name }
list.items.concat constants.map { |constant| list.items.concat constants.map { |constant|
parts = constant.comment.parts if constant.comment parts = constant.comment.parse.parts
parts << RDoc::Markup::Paragraph.new('[not documented]') if parts << RDoc::Markup::Paragraph.new('[not documented]') if
parts.empty? parts.empty?
@ -721,7 +721,7 @@ or the PAGER environment variable.
# Returns the stores wherein +name+ is found along with the classes, # Returns the stores wherein +name+ is found along with the classes,
# extends and includes that match it # extends and includes that match it
def classes_and_includes_and_extends_for name def classes_and_includes_and_extends_for(name)
klasses = [] klasses = []
extends = [] extends = []
includes = [] includes = []
@ -746,7 +746,7 @@ or the PAGER environment variable.
## ##
# Completes +name+ based on the caches. For Readline # Completes +name+ based on the caches. For Readline
def complete name def complete(name)
completions = [] completions = []
klass, selector, method = parse_name name klass, selector, method = parse_name name
@ -754,10 +754,10 @@ or the PAGER environment variable.
complete_klass name, klass, selector, method, completions complete_klass name, klass, selector, method, completions
complete_method name, klass, selector, completions complete_method name, klass, selector, completions
completions.sort.uniq completions.uniq.select {|s| s.start_with? name }.sort
end end
def complete_klass name, klass, selector, method, completions # :nodoc: def complete_klass(name, klass, selector, method, completions) # :nodoc:
klasses = classes.keys klasses = classes.keys
# may need to include Foo when given Foo:: # may need to include Foo when given Foo::
@ -776,7 +776,7 @@ or the PAGER environment variable.
end end
end end
def complete_method name, klass, selector, completions # :nodoc: def complete_method(name, klass, selector, completions) # :nodoc:
if completions.include? klass and name =~ /#|\.|::/ then if completions.include? klass and name =~ /#|\.|::/ then
methods = list_methods_matching name methods = list_methods_matching name
@ -789,14 +789,22 @@ or the PAGER environment variable.
completions << "#{klass}#{selector}" completions << "#{klass}#{selector}"
end end
completions.concat methods methods.each do |klass_sel_method|
match = klass_sel_method.match(/^(.+)(#|\.|::)([^#.:]+)$/)
# match[2] is `::` for class method and `#` for instance method.
# To be consistent with old completion that completes `['Foo#i', 'Foo::c']` for `Foo.`,
# `.` should be a wildcard for both `#` and `::` here.
if match && match[2] == selector || selector == '.'
completions << match[1] + selector + match[3]
end
end
end end
end end
## ##
# Converts +document+ to text and writes it to the pager # Converts +document+ to text and writes it to the pager
def display document def display(document)
page do |io| page do |io|
f = formatter(io) f = formatter(io)
f.width = @width if @width and f.respond_to?(:width) f.width = @width if @width and f.respond_to?(:width)
@ -809,7 +817,7 @@ or the PAGER environment variable.
## ##
# Outputs formatted RI data for class +name+. Groups undocumented classes # Outputs formatted RI data for class +name+. Groups undocumented classes
def display_class name def display_class(name)
return if name =~ /#|\./ return if name =~ /#|\./
found, klasses, includes, extends = found, klasses, includes, extends =
@ -825,7 +833,7 @@ or the PAGER environment variable.
## ##
# Outputs formatted RI data for method +name+ # Outputs formatted RI data for method +name+
def display_method name def display_method(name)
out = RDoc::Markup::Document.new out = RDoc::Markup::Document.new
add_method out, name add_method out, name
@ -841,7 +849,7 @@ or the PAGER environment variable.
# Returns true if +name+ was found, false if it was not an alternative could # Returns true if +name+ was found, false if it was not an alternative could
# be guessed, raises an error if +name+ couldn't be guessed. # be guessed, raises an error if +name+ couldn't be guessed.
def display_name name def display_name(name)
if name =~ /\w:(\w|$)/ then if name =~ /\w:(\w|$)/ then
display_page name display_page name
return true return true
@ -870,7 +878,7 @@ or the PAGER environment variable.
## ##
# Displays each name in +name+ # Displays each name in +name+
def display_names names def display_names(names)
names.each do |name| names.each do |name|
name = expand_name name name = expand_name name
@ -881,7 +889,7 @@ or the PAGER environment variable.
## ##
# Outputs formatted RI data for page +name+. # Outputs formatted RI data for page +name+.
def display_page name def display_page(name)
store_name, page_name = name.split ':', 2 store_name, page_name = name.split ':', 2
store = @stores.find { |s| s.source == store_name } store = @stores.find { |s| s.source == store_name }
@ -906,13 +914,13 @@ or the PAGER environment variable.
page = store.load_page page_name page = store.load_page page_name
display page.comment display page.comment.parse
end end
## ##
# Outputs a formatted RI page list for the pages in +store+. # Outputs a formatted RI page list for the pages in +store+.
def display_page_list store, pages = store.cache[:pages], search = nil def display_page_list(store, pages = store.cache[:pages], search = nil)
out = RDoc::Markup::Document.new out = RDoc::Markup::Document.new
title = if search then title = if search then
@ -956,7 +964,7 @@ or the PAGER environment variable.
# Expands abbreviated klass +klass+ into a fully-qualified class. "Zl::Da" # Expands abbreviated klass +klass+ into a fully-qualified class. "Zl::Da"
# will be expanded to Zlib::DataError. # will be expanded to Zlib::DataError.
def expand_class klass def expand_class(klass)
class_names = classes.keys class_names = classes.keys
ary = class_names.grep(Regexp.new("\\A#{klass.gsub(/(?=::|\z)/, '[^:]*')}\\z")) ary = class_names.grep(Regexp.new("\\A#{klass.gsub(/(?=::|\z)/, '[^:]*')}\\z"))
if ary.length != 1 && ary.first != klass if ary.length != 1 && ary.first != klass
@ -974,7 +982,7 @@ or the PAGER environment variable.
# Expands the class portion of +name+ into a fully-qualified class. See # Expands the class portion of +name+ into a fully-qualified class. See
# #expand_class. # #expand_class.
def expand_name name def expand_name(name)
klass, selector, method = parse_name name klass, selector, method = parse_name name
return [selector, method].join if klass.empty? return [selector, method].join if klass.empty?
@ -990,7 +998,7 @@ or the PAGER environment variable.
## ##
# Filters the methods in +found+ trying to find a match for +name+. # Filters the methods in +found+ trying to find a match for +name+.
def filter_methods found, name def filter_methods(found, name)
regexp = name_regexp name regexp = name_regexp name
filtered = found.find_all do |store, methods| filtered = found.find_all do |store, methods|
@ -1008,7 +1016,7 @@ or the PAGER environment variable.
# types of methods to look up (from #method_type), and the method name being # types of methods to look up (from #method_type), and the method name being
# searched for # searched for
def find_methods name def find_methods(name)
klass, selector, method = parse_name name klass, selector, method = parse_name name
types = method_type selector types = method_type selector
@ -1054,7 +1062,7 @@ or the PAGER environment variable.
# #
# See also RDoc::Store#source # See also RDoc::Store#source
def find_store name def find_store(name)
@stores.each do |store| @stores.each do |store|
source = store.source source = store.source
@ -1123,7 +1131,7 @@ or the PAGER environment variable.
# Lists classes known to ri starting with +names+. If +names+ is empty all # Lists classes known to ri starting with +names+. If +names+ is empty all
# known classes are shown. # known classes are shown.
def list_known_classes names = [] def list_known_classes(names = [])
classes = [] classes = []
stores.each do |store| stores.each do |store|
@ -1155,7 +1163,7 @@ or the PAGER environment variable.
## ##
# Returns an Array of methods matching +name+ # Returns an Array of methods matching +name+
def list_methods_matching name def list_methods_matching(name)
found = [] found = []
find_methods name do |store, klass, ancestor, types, method| find_methods name do |store, klass, ancestor, types, method|
@ -1194,7 +1202,7 @@ or the PAGER environment variable.
# Loads RI data for method +name+ on +klass+ from +store+. +type+ and # Loads RI data for method +name+ on +klass+ from +store+. +type+ and
# +cache+ indicate if it is a class or instance method. # +cache+ indicate if it is a class or instance method.
def load_method store, cache, klass, type, name def load_method(store, cache, klass, type, name)
methods = store.public_send(cache)[klass] methods = store.public_send(cache)[klass]
return unless methods return unless methods
@ -1207,7 +1215,8 @@ or the PAGER environment variable.
store.load_method klass, "#{type}#{method}" store.load_method klass, "#{type}#{method}"
rescue RDoc::Store::MissingFileError => e rescue RDoc::Store::MissingFileError => e
comment = RDoc::Comment.new("missing documentation at #{e.file}").parse comment = RDoc::Comment.new("missing documentation at #{e.file}")
comment.parse
method = RDoc::AnyMethod.new nil, name method = RDoc::AnyMethod.new nil, name
method.comment = comment method.comment = comment
@ -1217,7 +1226,7 @@ or the PAGER environment variable.
## ##
# Returns an Array of RI data for methods matching +name+ # Returns an Array of RI data for methods matching +name+
def load_methods_matching name def load_methods_matching(name)
found = [] found = []
find_methods name do |store, klass, ancestor, types, method| find_methods name do |store, klass, ancestor, types, method|
@ -1238,7 +1247,7 @@ or the PAGER environment variable.
## ##
# Returns a filtered list of methods matching +name+ # Returns a filtered list of methods matching +name+
def lookup_method name def lookup_method(name)
found = load_methods_matching name found = load_methods_matching name
if found.empty? if found.empty?
@ -1263,7 +1272,7 @@ or the PAGER environment variable.
## ##
# Builds a RDoc::Markup::Document from +found+, +klasses+ and +includes+ # Builds a RDoc::Markup::Document from +found+, +klasses+ and +includes+
def method_document out, name, filtered def method_document(out, name, filtered)
out << RDoc::Markup::Heading.new(1, name) out << RDoc::Markup::Heading.new(1, name)
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
@ -1279,7 +1288,7 @@ or the PAGER environment variable.
## ##
# Returns the type of method (:both, :instance, :class) for +selector+ # Returns the type of method (:both, :instance, :class) for +selector+
def method_type selector def method_type(selector)
case selector case selector
when '.', nil then :both when '.', nil then :both
when '#' then :instance when '#' then :instance
@ -1291,7 +1300,7 @@ or the PAGER environment variable.
# Returns a regular expression for +name+ that will match an # Returns a regular expression for +name+ that will match an
# RDoc::AnyMethod's name. # RDoc::AnyMethod's name.
def name_regexp name def name_regexp(name)
klass, type, name = parse_name name klass, type, name = parse_name name
case type case type
@ -1334,7 +1343,7 @@ or the PAGER environment variable.
# NOTE: Given Foo::Bar, Bar is considered a class even though it may be a # NOTE: Given Foo::Bar, Bar is considered a class even though it may be a
# method # method
def parse_name name def parse_name(name)
parts = name.split(/(::?|#|\.)/) parts = name.split(/(::?|#|\.)/)
if parts.length == 1 then if parts.length == 1 then
@ -1366,14 +1375,14 @@ or the PAGER environment variable.
# Renders the +klass+ from +store+ to +out+. If the klass has no # Renders the +klass+ from +store+ to +out+. If the klass has no
# documentable items the class is added to +also_in+ instead. # documentable items the class is added to +also_in+ instead.
def render_class out, store, klass, also_in # :nodoc: def render_class(out, store, klass, also_in) # :nodoc:
comment = klass.comment document = klass.comment.parse
# TODO the store's cache should always return an empty Array # TODO the store's cache should always return an empty Array
class_methods = store.class_methods[klass.full_name] || [] class_methods = store.class_methods[klass.full_name] || []
instance_methods = store.instance_methods[klass.full_name] || [] instance_methods = store.instance_methods[klass.full_name] || []
attributes = store.attributes[klass.full_name] || [] attributes = store.attributes[klass.full_name] || []
if comment.empty? and if document.empty? and
instance_methods.empty? and class_methods.empty? then instance_methods.empty? and class_methods.empty? then
also_in << store also_in << store
return return
@ -1381,7 +1390,7 @@ or the PAGER environment variable.
add_from out, store add_from out, store
class_document_comment out, comment class_document_comment out, document
if class_methods or instance_methods or not klass.constants.empty? then if class_methods or instance_methods or not klass.constants.empty? then
out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Rule.new(1)
@ -1396,7 +1405,7 @@ or the PAGER environment variable.
add_method_documentation out, klass if @show_all add_method_documentation out, klass if @show_all
end end
def render_method out, store, method, name # :nodoc: def render_method(out, store, method, name) # :nodoc:
out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
unless name =~ /^#{Regexp.escape method.parent_name}/ then unless name =~ /^#{Regexp.escape method.parent_name}/ then
@ -1416,7 +1425,7 @@ or the PAGER environment variable.
end end
end end
def render_method_arguments out, arglists # :nodoc: def render_method_arguments(out, arglists) # :nodoc:
return unless arglists return unless arglists
arglists = arglists.chomp.split "\n" arglists = arglists.chomp.split "\n"
@ -1425,25 +1434,25 @@ or the PAGER environment variable.
out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Rule.new(1)
end end
def render_method_comment out, method, alias_for = nil# :nodoc: def render_method_comment(out, method, alias_for = nil)# :nodoc:
if alias_for if alias_for
unless method.comment.nil? or method.comment.empty? unless method.comment.nil? or method.comment.empty?
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << method.comment out << method.comment.parse
end end
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << RDoc::Markup::Paragraph.new("(This method is an alias for #{alias_for.full_name}.)") out << RDoc::Markup::Paragraph.new("(This method is an alias for #{alias_for.full_name}.)")
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << alias_for.comment out << alias_for.comment.parse
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
else else
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << method.comment out << method.comment.parse
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
end end
end end
def render_method_superclass out, method # :nodoc: def render_method_superclass(out, method) # :nodoc:
return unless return unless
method.respond_to?(:superclass_method) and method.superclass_method method.respond_to?(:superclass_method) and method.superclass_method
@ -1551,7 +1560,7 @@ or the PAGER environment variable.
found_pages.each do |page| found_pages.each do |page|
out << RDoc::Markup::Heading.new(4, "Expanded from #{page.full_name}") out << RDoc::Markup::Heading.new(4, "Expanded from #{page.full_name}")
out << RDoc::Markup::BlankLine.new out << RDoc::Markup::BlankLine.new
out << page.comment out << page.comment.parse
end end
end end
end end

View file

@ -52,7 +52,7 @@ module RDoc::RI::Paths
## ##
# The ri directory for the gem with +gem_name+. # The ri directory for the gem with +gem_name+.
def self.gem_dir name, version def self.gem_dir(name, version)
req = Gem::Requirement.new "= #{version}" req = Gem::Requirement.new "= #{version}"
spec = Gem::Specification.find_by_name name, req spec = Gem::Specification.find_by_name name, req
@ -67,7 +67,7 @@ module RDoc::RI::Paths
# A +filter+ :all includes all versions of gems and includes gems without # A +filter+ :all includes all versions of gems and includes gems without
# ri documentation. # ri documentation.
def self.gemdirs filter = :latest def self.gemdirs(filter = :latest)
ri_paths = {} ri_paths = {}
all = Gem::Specification.map do |spec| all = Gem::Specification.map do |spec|

View file

@ -44,7 +44,7 @@ class RDoc::RI::Task < RDoc::Task
# Create an ri task with the given name. See RDoc::Task for documentation on # Create an ri task with the given name. See RDoc::Task for documentation on
# setting names. # setting names.
def initialize name = DEFAULT_NAMES # :yield: self def initialize(name = DEFAULT_NAMES) # :yield: self
super super
end end

View file

@ -51,7 +51,7 @@ class RDoc::RubyGemsHook
# Post installs hook that generates documentation for each specification in # Post installs hook that generates documentation for each specification in
# +specs+ # +specs+
def self.generate installer, specs def self.generate(installer, specs)
start = Time.now start = Time.now
types = installer.document types = installer.document
@ -70,7 +70,7 @@ class RDoc::RubyGemsHook
say "Done installing documentation for #{names} after #{duration} seconds" say "Done installing documentation for #{names} after #{duration} seconds"
end end
def self.remove uninstaller def self.remove(uninstaller)
new(uninstaller.spec).remove new(uninstaller.spec).remove
end end
@ -92,7 +92,7 @@ class RDoc::RubyGemsHook
# #
# Only +generate_ri+ is enabled by default. # Only +generate_ri+ is enabled by default.
def initialize spec, generate_rdoc = false, generate_ri = true def initialize(spec, generate_rdoc = false, generate_ri = true)
@doc_dir = spec.doc_dir @doc_dir = spec.doc_dir
@force = false @force = false
@rdoc = nil @rdoc = nil
@ -110,7 +110,7 @@ class RDoc::RubyGemsHook
#-- #--
# TODO move to RDoc::Options # TODO move to RDoc::Options
def delete_legacy_args args def delete_legacy_args(args)
args.delete '--inline-source' args.delete '--inline-source'
args.delete '--promiscuous' args.delete '--promiscuous'
args.delete '-p' args.delete '-p'
@ -123,7 +123,7 @@ class RDoc::RubyGemsHook
# #
# Documentation will be generated into +destination+ # Documentation will be generated into +destination+
def document generator, options, destination def document(generator, options, destination)
generator_name = generator generator_name = generator
options = options.dup options = options.dup
@ -181,25 +181,22 @@ class RDoc::RubyGemsHook
options = ::RDoc::Options.new options = ::RDoc::Options.new
options.default_title = "#{@spec.full_name} Documentation" options.default_title = "#{@spec.full_name} Documentation"
options.parse args options.parse args
options.quiet = !Gem.configuration.really_verbose
end end
options.quiet = !Gem.configuration.really_verbose
@rdoc = new_rdoc @rdoc = new_rdoc
@rdoc.options = options
store = RDoc::Store.new
store.encoding = options.encoding
store.dry_run = options.dry_run
store.main = options.main_page
store.title = options.title
@rdoc.store = store
say "Parsing documentation for #{@spec.full_name}" say "Parsing documentation for #{@spec.full_name}"
Dir.chdir @spec.full_gem_path do Dir.chdir @spec.full_gem_path do
@rdoc.parse_files options.files # RDoc::Options#finish must be called before parse_files.
# RDoc::Options#finish is also called after ri/darkfish generator setup.
# We need to dup the options to avoid modifying it after finish is called.
parse_options = options.dup
parse_options.finish
@rdoc.options = parse_options
@rdoc.store = RDoc::Store.new(parse_options)
@rdoc.parse_files parse_options.files
end end
document 'ri', options, @ri_dir if document 'ri', options, @ri_dir if
@ -303,12 +300,28 @@ module RDoc
RubyGemsHook.new(@spec).remove RubyGemsHook.new(@spec).remove
end end
def self.generation_hook installer, specs def self.generation_hook(installer, specs)
# Do nothing if this is NOT a default gem. # Do nothing if this is NOT a default gem.
return unless default_gem? return unless default_gem?
# Generate document for compatibility if this is a default gem. # Generate document for compatibility if this is a default gem.
RubyGemsHook.generate(installer, specs) RubyGemsHook.generate(installer, specs)
end end
def self.load_rdoc
RubyGemsHook.load_rdoc
end
def self.rdoc_version
RubyGemsHook.rdoc_version
end
def rdoc_installed?
RubyGemsHook.new(@spec).rdoc_installed?
end
def ri_installed?
RubyGemsHook.new(@spec).ri_installed?
end
end end
end end

View file

@ -66,7 +66,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
# +server+ is provided automatically by WEBrick when mounting. +stores+ and # +server+ is provided automatically by WEBrick when mounting. +stores+ and
# +cache+ are provided automatically by the servlet. # +cache+ are provided automatically by the servlet.
def initialize server, stores, cache, mount_path = nil, extra_doc_dirs = [] def initialize(server, stores, cache, mount_path = nil, extra_doc_dirs = [])
super server super server
@cache = cache @cache = cache
@ -97,7 +97,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
## ##
# Serves the asset at the path in +req+ for +generator_name+ via +res+. # Serves the asset at the path in +req+ for +generator_name+ via +res+.
def asset generator_name, req, res def asset(generator_name, req, res)
asset_dir = @asset_dirs[generator_name] asset_dir = @asset_dirs[generator_name]
asset_path = File.join asset_dir, req.path asset_path = File.join asset_dir, req.path
@ -116,7 +116,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
## ##
# GET request entry point. Fills in +res+ for the path, etc. in +req+. # GET request entry point. Fills in +res+ for the path, etc. in +req+.
def do_GET req, res def do_GET(req, res)
req.path.sub!(/\A#{Regexp.escape @mount_path}/, '') if @mount_path req.path.sub!(/\A#{Regexp.escape @mount_path}/, '') if @mount_path
case req.path case req.path
@ -133,7 +133,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
show_documentation req, res show_documentation req, res
end end
rescue WEBrick::HTTPStatus::NotFound => e rescue WEBrick::HTTPStatus::NotFound => e
generator = generator_for RDoc::Store.new generator = generator_for RDoc::Store.new(@options)
not_found generator, req, res, e.message not_found generator, req, res, e.message
rescue WEBrick::HTTPStatus::Status rescue WEBrick::HTTPStatus::Status
@ -149,7 +149,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
# module or page name (/RDoc/Servlet.html becomes RDoc::Servlet). # module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
# +generator+ is used to create the page. # +generator+ is used to create the page.
def documentation_page store, generator, path, req, res def documentation_page(store, generator, path, req, res)
text_name = path.chomp '.html' text_name = path.chomp '.html'
name = text_name.gsub '/', '::' name = text_name.gsub '/', '::'
@ -168,7 +168,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
# Creates the JSON search index on +res+ for the given +store+. +generator+ # Creates the JSON search index on +res+ for the given +store+. +generator+
# must respond to \#json_index to build. +req+ is ignored. # must respond to \#json_index to build. +req+ is ignored.
def documentation_search store, generator, req, res def documentation_search(store, generator, req, res)
json_index = @cache[store].fetch :json_index do json_index = @cache[store].fetch :json_index do
@cache[store][:json_index] = @cache[store][:json_index] =
JSON.dump generator.json_index.build_index JSON.dump generator.json_index.build_index
@ -182,7 +182,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
# Returns the RDoc::Store and path relative to +mount_path+ for # Returns the RDoc::Store and path relative to +mount_path+ for
# documentation at +path+. # documentation at +path+.
def documentation_source path def documentation_source(path)
_, source_name, path = path.split '/', 3 _, source_name, path = path.split '/', 3
store = @stores[source_name] store = @stores[source_name]
@ -200,7 +200,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
## ##
# Generates an error page for the +exception+ while handling +req+ on +res+. # Generates an error page for the +exception+ while handling +req+ on +res+.
def error exception, req, res def error(exception, req, res)
backtrace = exception.backtrace.join "\n" backtrace = exception.backtrace.join "\n"
res.content_type = 'text/html' res.content_type = 'text/html'
@ -243,10 +243,11 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
## ##
# Instantiates a Darkfish generator for +store+ # Instantiates a Darkfish generator for +store+
def generator_for store def generator_for(store)
generator = RDoc::Generator::Darkfish.new store, @options generator = RDoc::Generator::Darkfish.new store, @options
generator.file_output = false generator.file_output = false
generator.asset_rel_path = '..' generator.asset_rel_path = '..'
generator.setup
rdoc = RDoc::RDoc.new rdoc = RDoc::RDoc.new
rdoc.store = store rdoc.store = store
@ -264,7 +265,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
# file has not been modified a Not Modified response is returned. 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+. # file has been modified a Last-Modified header is added to +res+.
def if_modified_since req, res, path = nil def if_modified_since(req, res, path = nil)
last_modified = File.stat(path).mtime if path last_modified = File.stat(path).mtime if path
res['last-modified'] = last_modified.httpdate res['last-modified'] = last_modified.httpdate
@ -290,7 +291,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
def installed_docs def installed_docs
extra_counter = 0 extra_counter = 0
ri_paths.map do |path, type| ri_paths.map do |path, type|
store = RDoc::Store.new path, type store = RDoc::Store.new(@options, path: path, type: type)
exists = File.exist? store.cache_path exists = File.exist? store.cache_path
case type case type
@ -315,7 +316,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
## ##
# Returns a 404 page built by +generator+ for +req+ on +res+. # Returns a 404 page built by +generator+ for +req+ on +res+.
def not_found generator, req, res, message = nil def not_found(generator, req, res, message = nil)
message ||= "The page <kbd>#{ERB::Util.h req.path}</kbd> was not found" message ||= "The page <kbd>#{ERB::Util.h req.path}</kbd> was not found"
res.body = generator.generate_servlet_not_found message res.body = generator.generate_servlet_not_found message
res.status = 404 res.status = 404
@ -324,14 +325,14 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
## ##
# Enumerates the ri paths. See RDoc::RI::Paths#each # Enumerates the ri paths. See RDoc::RI::Paths#each
def ri_paths &block def ri_paths(&block)
RDoc::RI::Paths.each true, true, true, :all, *@extra_doc_dirs, &block #TODO: pass extra_dirs RDoc::RI::Paths.each true, true, true, :all, *@extra_doc_dirs, &block #TODO: pass extra_dirs
end end
## ##
# Generates the root page on +res+. +req+ is ignored. # Generates the root page on +res+. +req+ is ignored.
def root req, res def root(req, res)
generator = RDoc::Generator::Darkfish.new nil, @options generator = RDoc::Generator::Darkfish.new nil, @options
res.body = generator.generate_servlet_root installed_docs res.body = generator.generate_servlet_root installed_docs
@ -342,7 +343,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
## ##
# Generates a search index for the root page on +res+. +req+ is ignored. # Generates a search index for the root page on +res+. +req+ is ignored.
def root_search req, res def root_search(req, res)
search_index = [] search_index = []
info = [] info = []
@ -392,7 +393,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
# Displays documentation for +req+ on +res+, whether that be HTML or some # Displays documentation for +req+ on +res+, whether that be HTML or some
# asset. # asset.
def show_documentation req, res def show_documentation(req, res)
store, path = documentation_source req.path store, path = documentation_source req.path
if_modified_since req, res, store.cache_path if_modified_since req, res, store.cache_path
@ -416,18 +417,18 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
## ##
# Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name). # Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
def store_for source_name def store_for(source_name)
case source_name case source_name
when 'home' then when 'home' then
RDoc::Store.new RDoc::RI::Paths.home_dir, :home RDoc::Store.new(@options, path: RDoc::RI::Paths.home_dir, type: :home)
when 'ruby' then when 'ruby' then
RDoc::Store.new RDoc::RI::Paths.system_dir, :system RDoc::Store.new(@options, path: RDoc::RI::Paths.system_dir, type: :system)
when 'site' then when 'site' then
RDoc::Store.new RDoc::RI::Paths.site_dir, :site RDoc::Store.new(@options, path: RDoc::RI::Paths.site_dir, type: :site)
when /\Aextra-(\d+)\z/ then when /\Aextra-(\d+)\z/ then
index = $1.to_i - 1 index = $1.to_i - 1
ri_dir = installed_docs[index][4] ri_dir = installed_docs[index][4]
RDoc::Store.new ri_dir, :extra RDoc::Store.new(@options, path: ri_dir, type: :extra)
else else
ri_dir, type = ri_paths.find do |dir, dir_type| ri_dir, type = ri_paths.find do |dir, dir_type|
next unless dir_type == :gem next unless dir_type == :gem
@ -438,7 +439,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
raise WEBrick::HTTPStatus::NotFound, raise WEBrick::HTTPStatus::NotFound,
"Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir "Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir
store = RDoc::Store.new ri_dir, type store = RDoc::Store.new(@options, path: ri_dir, type: type)
return store if File.exist? store.cache_path return store if File.exist? store.cache_path

View file

@ -26,7 +26,7 @@ class RDoc::Stats
# Creates a new Stats that will have +num_files+. +verbosity+ defaults to 1 # Creates a new Stats that will have +num_files+. +verbosity+ defaults to 1
# which will create an RDoc::Stats::Normal outputter. # which will create an RDoc::Stats::Normal outputter.
def initialize store, num_files, verbosity = 1 def initialize(store, num_files, verbosity = 1)
@num_files = num_files @num_files = num_files
@store = store @store = store
@ -49,28 +49,28 @@ class RDoc::Stats
## ##
# Records the parsing of an alias +as+. # Records the parsing of an alias +as+.
def add_alias as def add_alias(as)
@display.print_alias as @display.print_alias as
end end
## ##
# Records the parsing of an attribute +attribute+ # Records the parsing of an attribute +attribute+
def add_attribute attribute def add_attribute(attribute)
@display.print_attribute attribute @display.print_attribute attribute
end end
## ##
# Records the parsing of a class +klass+ # Records the parsing of a class +klass+
def add_class klass def add_class(klass)
@display.print_class klass @display.print_class klass
end end
## ##
# Records the parsing of +constant+ # Records the parsing of +constant+
def add_constant constant def add_constant(constant)
@display.print_constant constant @display.print_constant constant
end end
@ -155,7 +155,7 @@ class RDoc::Stats
# 0:: Classes, modules, constants, attributes, methods # 0:: Classes, modules, constants, attributes, methods
# 1:: Level 0 + method parameters # 1:: Level 0 + method parameters
def coverage_level= level def coverage_level=(level)
level = -1 unless level level = -1 unless level
@coverage_level = level @coverage_level = level
@ -164,7 +164,7 @@ class RDoc::Stats
## ##
# Returns the length and number of undocumented items in +collection+. # Returns the length and number of undocumented items in +collection+.
def doc_stats collection def doc_stats(collection)
visible = collection.select { |item| item.display? } visible = collection.select { |item| item.display? }
[visible.length, visible.count { |item| not item.documented? }] [visible.length, visible.count { |item| not item.documented? }]
end end
@ -256,12 +256,12 @@ class RDoc::Stats
## ##
# Returns a report on undocumented attributes in ClassModule +cm+ # Returns a report on undocumented attributes in ClassModule +cm+
def report_attributes cm def report_attributes(cm)
return if cm.attributes.empty? return if cm.attributes.empty?
report = [] report = []
cm.each_attribute do |attr| cm.attributes.each do |attr|
next if attr.documented? next if attr.documented?
line = attr.line ? ":#{attr.line}" : nil line = attr.line ? ":#{attr.line}" : nil
report << " #{attr.definition} :#{attr.name} # in file #{attr.file.full_name}#{line}\n" report << " #{attr.definition} :#{attr.name} # in file #{attr.file.full_name}#{line}\n"
@ -274,7 +274,7 @@ class RDoc::Stats
## ##
# Returns a report on undocumented items in ClassModule +cm+ # Returns a report on undocumented items in ClassModule +cm+
def report_class_module cm def report_class_module(cm)
return if cm.fully_documented? and @coverage_level.zero? return if cm.fully_documented? and @coverage_level.zero?
return unless cm.display? return unless cm.display?
@ -326,12 +326,12 @@ class RDoc::Stats
## ##
# Returns a report on undocumented constants in ClassModule +cm+ # Returns a report on undocumented constants in ClassModule +cm+
def report_constants cm def report_constants(cm)
return if cm.constants.empty? return if cm.constants.empty?
report = [] report = []
cm.each_constant do |constant| cm.constants.each do |constant|
# TODO constant aliases are listed in the summary but not reported # TODO constant aliases are listed in the summary but not reported
# figure out what to do here # figure out what to do here
next if constant.documented? || constant.is_alias_for next if constant.documented? || constant.is_alias_for
@ -348,7 +348,7 @@ class RDoc::Stats
## ##
# Returns a report on undocumented methods in ClassModule +cm+ # Returns a report on undocumented methods in ClassModule +cm+
def report_methods cm def report_methods(cm)
return if cm.method_list.empty? return if cm.method_list.empty?
report = [] report = []
@ -436,7 +436,7 @@ class RDoc::Stats
# Determines which parameters in +method+ were not documented. Returns a # Determines which parameters in +method+ were not documented. Returns a
# total parameter count and an Array of undocumented methods. # total parameter count and an Array of undocumented methods.
def undoc_params method def undoc_params(method)
@formatter ||= RDoc::Markup::ToTtOnly.new @formatter ||= RDoc::Markup::ToTtOnly.new
params = method.param_list params = method.param_list

View file

@ -20,7 +20,7 @@ class RDoc::Stats::Normal < RDoc::Stats::Quiet
## ##
# Prints a file with a progress bar # Prints a file with a progress bar
def print_file files_so_far, filename def print_file(files_so_far, filename)
progress_bar = sprintf("%3d%% [%2d/%2d] ", progress_bar = sprintf("%3d%% [%2d/%2d] ",
100 * files_so_far / @num_files, 100 * files_so_far / @num_files,
files_so_far, files_so_far,

View file

@ -7,7 +7,7 @@ class RDoc::Stats::Quiet
## ##
# Creates a new Quiet that will print nothing # Creates a new Quiet that will print nothing
def initialize num_files def initialize(num_files)
@num_files = num_files @num_files = num_files
end end

View file

@ -8,15 +8,15 @@ class RDoc::Stats::Verbose < RDoc::Stats::Normal
## ##
# Returns a marker for RDoc::CodeObject +co+ being undocumented # Returns a marker for RDoc::CodeObject +co+ being undocumented
def nodoc co def nodoc(co)
" (undocumented)" unless co.documented? " (undocumented)" unless co.documented?
end end
def print_alias as # :nodoc: def print_alias(as) # :nodoc:
puts " alias #{as.new_name} #{as.old_name}#{nodoc as}" puts " alias #{as.new_name} #{as.old_name}#{nodoc as}"
end end
def print_attribute attribute # :nodoc: def print_attribute(attribute) # :nodoc:
puts " #{attribute.definition} #{attribute.name}#{nodoc attribute}" puts " #{attribute.definition} #{attribute.name}#{nodoc attribute}"
end end

View file

@ -54,7 +54,7 @@ class RDoc::Store
# Creates a new MissingFileError for the missing +file+ for the given # Creates a new MissingFileError for the missing +file+ for the given
# +name+ that should have been in the +store+. # +name+ that should have been in the +store+.
def initialize store, file, name def initialize(store, file, name)
@store = store @store = store
@file = file @file = file
@name = name @name = name
@ -94,11 +94,7 @@ class RDoc::Store
attr_accessor :path attr_accessor :path
## attr_reader :options
# The RDoc::RDoc driver for this parse tree. This allows classes consulting
# the documentation tree to access user-set options, for example.
attr_accessor :rdoc
## ##
# Type of ri datastore this was loaded from. See RDoc::RI::Driver, # Type of ri datastore this was loaded from. See RDoc::RI::Driver,
@ -124,11 +120,11 @@ class RDoc::Store
## ##
# Creates a new Store of +type+ that will load or save to +path+ # Creates a new Store of +type+ that will load or save to +path+
def initialize path = nil, type = nil def initialize(options, path: nil, type: nil)
@dry_run = false @options = options
@encoding = nil @dry_run = options.dry_run
@path = path @encoding = options.encoding
@rdoc = nil @path = path || options.op_dir
@type = type @type = type
@cache = { @cache = {
@ -139,10 +135,10 @@ class RDoc::Store
:c_singleton_class_variables => {}, :c_singleton_class_variables => {},
:encoding => @encoding, :encoding => @encoding,
:instance_methods => {}, :instance_methods => {},
:main => nil, :main => options.main_page,
:modules => [], :modules => [],
:pages => [], :pages => [],
:title => nil, :title => options.title,
} }
@classes_hash = {} @classes_hash = {}
@ -166,14 +162,14 @@ class RDoc::Store
# Adds +module+ as an enclosure (namespace) for the given +variable+ for C # Adds +module+ as an enclosure (namespace) for the given +variable+ for C
# files. # files.
def add_c_enclosure variable, namespace def add_c_enclosure(variable, namespace)
@c_enclosure_classes[variable] = namespace @c_enclosure_classes[variable] = namespace
end end
## ##
# Adds C variables from an RDoc::Parser::C # Adds C variables from an RDoc::Parser::C
def add_c_variables c_parser def add_c_variables(c_parser)
filename = c_parser.top_level.relative_name filename = c_parser.top_level.relative_name
@c_class_variables[filename] = make_variable_map c_parser.classes @c_class_variables[filename] = make_variable_map c_parser.classes
@ -185,7 +181,7 @@ class RDoc::Store
# Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the # Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the
# created RDoc::TopLevel. # created RDoc::TopLevel.
def add_file absolute_name, relative_name: absolute_name, parser: nil def add_file(absolute_name, relative_name: absolute_name, parser: nil)
unless top_level = @files_hash[relative_name] then unless top_level = @files_hash[relative_name] then
top_level = RDoc::TopLevel.new absolute_name, relative_name top_level = RDoc::TopLevel.new absolute_name, relative_name
top_level.parser = parser if parser top_level.parser = parser if parser
@ -272,7 +268,7 @@ class RDoc::Store
## ##
# Path to the ri data for +klass_name+ # Path to the ri data for +klass_name+
def class_file klass_name def class_file(klass_name)
name = klass_name.split('::').last name = klass_name.split('::').last
File.join class_path(klass_name), "cdesc-#{name}.ri" File.join class_path(klass_name), "cdesc-#{name}.ri"
end end
@ -288,7 +284,7 @@ class RDoc::Store
## ##
# Path where data for +klass_name+ will be stored (methods or class data) # Path where data for +klass_name+ will be stored (methods or class data)
def class_path klass_name def class_path(klass_name)
File.join @path, *klass_name.split('::') File.join @path, *klass_name.split('::')
end end
@ -303,7 +299,7 @@ class RDoc::Store
# Removes empty items and ensures item in each collection are unique and # Removes empty items and ensures item in each collection are unique and
# sorted # sorted
def clean_cache_collection collection # :nodoc: def clean_cache_collection(collection) # :nodoc:
collection.each do |name, item| collection.each do |name, item|
if item.empty? then if item.empty? then
collection.delete name collection.delete name
@ -331,7 +327,7 @@ class RDoc::Store
# #
# See also RDoc::Context#remove_from_documentation? # See also RDoc::Context#remove_from_documentation?
def complete min_visibility def complete(min_visibility)
fix_basic_object_inheritance fix_basic_object_inheritance
# cache included modules before they are removed from the documentation # cache included modules before they are removed from the documentation
@ -378,7 +374,7 @@ class RDoc::Store
## ##
# Finds the enclosure (namespace) for the given C +variable+. # Finds the enclosure (namespace) for the given C +variable+.
def find_c_enclosure variable def find_c_enclosure(variable)
@c_enclosure_classes.fetch variable do @c_enclosure_classes.fetch variable do
break unless name = @c_enclosure_names[variable] break unless name = @c_enclosure_names[variable]
@ -403,14 +399,14 @@ class RDoc::Store
## ##
# Finds the class with +name+ in all discovered classes # Finds the class with +name+ in all discovered classes
def find_class_named name def find_class_named(name)
@classes_hash[name] @classes_hash[name]
end end
## ##
# Finds the class with +name+ starting in namespace +from+ # Finds the class with +name+ starting in namespace +from+
def find_class_named_from name, from def find_class_named_from(name, from)
from = find_class_named from unless RDoc::Context === from from = find_class_named from unless RDoc::Context === from
until RDoc::TopLevel === from do until RDoc::TopLevel === from do
@ -428,7 +424,7 @@ class RDoc::Store
## ##
# Finds the class or module with +name+ # Finds the class or module with +name+
def find_class_or_module name def find_class_or_module(name)
name = $' if name =~ /^::/ name = $' if name =~ /^::/
@classes_hash[name] || @modules_hash[name] @classes_hash[name] || @modules_hash[name]
end end
@ -436,14 +432,14 @@ class RDoc::Store
## ##
# Finds the file with +name+ in all discovered files # Finds the file with +name+ in all discovered files
def find_file_named name def find_file_named(name)
@files_hash[name] @files_hash[name]
end end
## ##
# Finds the module with +name+ in all discovered modules # Finds the module with +name+ in all discovered modules
def find_module_named name def find_module_named(name)
@modules_hash[name] @modules_hash[name]
end end
@ -451,7 +447,7 @@ class RDoc::Store
# Returns the RDoc::TopLevel that is a text file and has the given # Returns the RDoc::TopLevel that is a text file and has the given
# +file_name+ # +file_name+
def find_text_page file_name def find_text_page(file_name)
@text_files_hash.each_value.find do |file| @text_files_hash.each_value.find do |file|
file.full_name == file_name file.full_name == file_name
end end
@ -464,7 +460,7 @@ class RDoc::Store
#-- #--
# TODO aliases should be registered by Context#add_module_alias # TODO aliases should be registered by Context#add_module_alias
def find_unique all_hash def find_unique(all_hash)
unique = [] unique = []
all_hash.each_pair do |full_name, cm| all_hash.each_pair do |full_name, cm|
@ -607,7 +603,7 @@ class RDoc::Store
## ##
# Loads ri data for +klass_name+ and hooks it up to this store. # Loads ri data for +klass_name+ and hooks it up to this store.
def load_class klass_name def load_class(klass_name)
obj = load_class_data klass_name obj = load_class_data klass_name
obj.store = self obj.store = self
@ -625,7 +621,7 @@ class RDoc::Store
## ##
# Loads ri data for +klass_name+ # Loads ri data for +klass_name+
def load_class_data klass_name def load_class_data(klass_name)
file = class_file klass_name file = class_file klass_name
marshal_load(file) marshal_load(file)
@ -638,7 +634,7 @@ class RDoc::Store
## ##
# Loads ri data for +method_name+ in +klass_name+ # Loads ri data for +method_name+ in +klass_name+
def load_method klass_name, method_name def load_method(klass_name, method_name)
file = method_file klass_name, method_name file = method_file klass_name, method_name
obj = marshal_load(file) obj = marshal_load(file)
@ -654,7 +650,7 @@ class RDoc::Store
## ##
# Loads ri data for +page_name+ # Loads ri data for +page_name+
def load_page page_name def load_page(page_name)
file = page_file page_name file = page_file page_name
obj = marshal_load(file) obj = marshal_load(file)
@ -677,7 +673,7 @@ class RDoc::Store
## ##
# Sets the main page for this RDoc store. # Sets the main page for this RDoc store.
def main= page def main=(page)
@cache[:main] = page @cache[:main] = page
end end
@ -685,7 +681,7 @@ class RDoc::Store
# Converts the variable => ClassModule map +variables+ from a C parser into # Converts the variable => ClassModule map +variables+ from a C parser into
# a variable => class name map. # a variable => class name map.
def make_variable_map variables def make_variable_map(variables)
map = {} map = {}
variables.each { |variable, class_module| variables.each { |variable, class_module|
@ -698,7 +694,7 @@ class RDoc::Store
## ##
# Path to the ri data for +method_name+ in +klass_name+ # Path to the ri data for +method_name+ in +klass_name+
def method_file klass_name, method_name def method_file(klass_name, method_name)
method_name = method_name.split('::').last method_name = method_name.split('::').last
method_name =~ /#(.*)/ method_name =~ /#(.*)/
method_type = $1 ? 'i' : 'c' method_type = $1 ? 'i' : 'c'
@ -726,7 +722,7 @@ class RDoc::Store
## ##
# Returns the RDoc::TopLevel that is a text file and has the given +name+ # Returns the RDoc::TopLevel that is a text file and has the given +name+
def page name def page(name)
@text_files_hash.each_value.find do |file| @text_files_hash.each_value.find do |file|
file.page_name == name or file.base_name == name file.page_name == name or file.base_name == name
end end
@ -735,7 +731,7 @@ class RDoc::Store
## ##
# Path to the ri data for +page_name+ # Path to the ri data for +page_name+
def page_file page_name def page_file(page_name)
file_name = File.basename(page_name).gsub('.', '_') file_name = File.basename(page_name).gsub('.', '_')
File.join @path, File.dirname(page_name), "page-#{file_name}.ri" File.join @path, File.dirname(page_name), "page-#{file_name}.ri"
@ -746,7 +742,7 @@ class RDoc::Store
# #
# See RDoc::Context#remove_from_documentation? # See RDoc::Context#remove_from_documentation?
def remove_nodoc all_hash def remove_nodoc(all_hash)
all_hash.keys.each do |name| all_hash.keys.each do |name|
context = all_hash[name] context = all_hash[name]
all_hash.delete(name) if context.remove_from_documentation? all_hash.delete(name) if context.remove_from_documentation?
@ -766,7 +762,7 @@ class RDoc::Store
save_method klass, method save_method klass, method
end end
klass.each_attribute do |attribute| klass.attributes.each do |attribute|
save_method klass, attribute save_method klass, attribute
end end
end end
@ -808,7 +804,7 @@ class RDoc::Store
## ##
# Writes the ri data for +klass+ (or module) # Writes the ri data for +klass+ (or module)
def save_class klass def save_class(klass)
full_name = klass.full_name full_name = klass.full_name
FileUtils.mkdir_p class_path(full_name) unless @dry_run FileUtils.mkdir_p class_path(full_name) unless @dry_run
@ -882,7 +878,7 @@ class RDoc::Store
## ##
# Writes the ri data for +method+ on +klass+ # Writes the ri data for +method+ on +klass+
def save_method klass, method def save_method(klass, method)
full_name = klass.full_name full_name = klass.full_name
FileUtils.mkdir_p class_path(full_name) unless @dry_run FileUtils.mkdir_p class_path(full_name) unless @dry_run
@ -905,7 +901,7 @@ class RDoc::Store
## ##
# Writes the ri data for +page+ # Writes the ri data for +page+
def save_page page def save_page(page)
return unless page.text? return unless page.text?
path = page_file page.full_name path = page_file page.full_name
@ -952,7 +948,7 @@ class RDoc::Store
## ##
# Sets the title page for this RDoc store. # Sets the title page for this RDoc store.
def title= title def title=(title)
@cache[:title] = title @cache[:title] = title
end end

View file

@ -154,7 +154,7 @@ class RDoc::Task < Rake::TaskLib
# Create an RDoc task with the given name. See the RDoc::Task class overview # Create an RDoc task with the given name. See the RDoc::Task class overview
# for documentation. # for documentation.
def initialize name = :rdoc # :yield: self def initialize(name = :rdoc) # :yield: self
defaults defaults
check_names name check_names name
@ -170,7 +170,7 @@ class RDoc::Task < Rake::TaskLib
# Ensures that +names+ only includes names for the :rdoc, :clobber_rdoc and # Ensures that +names+ only includes names for the :rdoc, :clobber_rdoc and
# :rerdoc. If other names are given an ArgumentError is raised. # :rerdoc. If other names are given an ArgumentError is raised.
def check_names names def check_names(names)
return unless Hash === names return unless Hash === names
invalid_options = invalid_options =

View file

@ -52,7 +52,7 @@ module RDoc::Text
## ##
# Transcodes +character+ to +encoding+ with a +fallback+ character. # Transcodes +character+ to +encoding+ with a +fallback+ character.
def self.encode_fallback character, encoding, fallback def self.encode_fallback(character, encoding, fallback)
character.encode(encoding, :fallback => { character => fallback }, character.encode(encoding, :fallback => { character => fallback },
:undef => :replace, :replace => fallback) :undef => :replace, :replace => fallback)
end end
@ -60,7 +60,7 @@ module RDoc::Text
## ##
# Expands tab characters in +text+ to eight spaces # Expands tab characters in +text+ to eight spaces
def expand_tabs text def expand_tabs(text)
expanded = [] expanded = []
text.each_line do |line| text.each_line do |line|
@ -79,7 +79,7 @@ module RDoc::Text
## ##
# Flush +text+ left based on the shortest line # Flush +text+ left based on the shortest line
def flush_left text def flush_left(text)
indent = 9999 indent = 9999
text.each_line do |line| text.each_line do |line|
@ -98,9 +98,9 @@ module RDoc::Text
# #
# Requires the including class to implement #formatter # Requires the including class to implement #formatter
def markup text def markup(text)
if @store.rdoc.options if @store.options
locale = @store.rdoc.options.locale locale = @store.options.locale
else else
locale = nil locale = nil
end end
@ -114,7 +114,7 @@ module RDoc::Text
## ##
# Strips hashes, expands tabs then flushes +text+ to the left # Strips hashes, expands tabs then flushes +text+ to the left
def normalize_comment text def normalize_comment(text)
return text if text.empty? return text if text.empty?
case language case language
@ -132,7 +132,7 @@ module RDoc::Text
## ##
# Normalizes +text+ then builds a RDoc::Markup::Document from it # Normalizes +text+ then builds a RDoc::Markup::Document from it
def parse text, format = 'rdoc' def parse(text, format = 'rdoc')
return text if RDoc::Markup::Document === text return text if RDoc::Markup::Document === text
return text.parse if RDoc::Comment === text return text.parse if RDoc::Comment === text
@ -146,7 +146,7 @@ module RDoc::Text
## ##
# The first +limit+ characters of +text+ as HTML # The first +limit+ characters of +text+ as HTML
def snippet text, limit = 100 def snippet(text, limit = 100)
document = parse text document = parse text
RDoc::Markup::ToHtmlSnippet.new(options, limit).convert document RDoc::Markup::ToHtmlSnippet.new(options, limit).convert document
@ -155,7 +155,7 @@ module RDoc::Text
## ##
# Strips leading # characters from +text+ # Strips leading # characters from +text+
def strip_hashes text def strip_hashes(text)
return text if text =~ /^(?>\s*)[^\#]/ return text if text =~ /^(?>\s*)[^\#]/
empty = '' empty = ''
@ -167,14 +167,14 @@ module RDoc::Text
## ##
# Strips leading and trailing \n characters from +text+ # Strips leading and trailing \n characters from +text+
def strip_newlines text def strip_newlines(text)
text.gsub(/\A\n*(.*?)\n*\z/m) do $1 end # block preserves String encoding text.gsub(/\A\n*(.*?)\n*\z/m) do $1 end # block preserves String encoding
end end
## ##
# Strips /* */ style comments # Strips /* */ style comments
def strip_stars text def strip_stars(text)
return text unless text =~ %r%/\*.*\*/%m return text unless text =~ %r%/\*.*\*/%m
encoding = text.encoding encoding = text.encoding
@ -197,7 +197,7 @@ module RDoc::Text
# Converts ampersand, dashes, ellipsis, quotes, copyright and registered # Converts ampersand, dashes, ellipsis, quotes, copyright and registered
# trademark symbols in +text+ to properly encoded characters. # trademark symbols in +text+ to properly encoded characters.
def to_html text def to_html(text)
html = (''.encode text.encoding).dup html = (''.encode text.encoding).dup
encoded = RDoc::Text::TO_HTML_CHARACTERS[text.encoding] encoded = RDoc::Text::TO_HTML_CHARACTERS[text.encoding]

View file

@ -13,7 +13,7 @@ module RDoc::TokenStream
# <tt><span></tt> elements. Some tokens types are wrapped in spans # <tt><span></tt> elements. Some tokens types are wrapped in spans
# with the given class names. Other token types are not wrapped in spans. # with the given class names. Other token types are not wrapped in spans.
def self.to_html token_stream def self.to_html(token_stream)
starting_title = false starting_title = false
token_stream.map do |t| token_stream.map do |t|

View file

@ -75,7 +75,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# #
# Returns an RDoc::Markup::Document representing the TomDoc format. # Returns an RDoc::Markup::Document representing the TomDoc format.
def self.parse text def self.parse(text)
parser = new parser = new
parser.tokenize text parser.tokenize text
@ -91,7 +91,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# #
# Returns a String containing the signature and nil if not # Returns a String containing the signature and nil if not
def self.signature comment def self.signature(comment)
return unless comment.tomdoc? return unless comment.tomdoc?
document = comment.parse document = comment.parse
@ -134,7 +134,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# #
# Returns an RDoc::Markup::Heading # Returns an RDoc::Markup::Heading
def build_heading level def build_heading(level)
heading = super heading = super
@section = heading.text @section = heading.text
@ -150,7 +150,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# #
# Returns an RDoc::Markup::Verbatim # Returns an RDoc::Markup::Verbatim
def build_verbatim margin def build_verbatim(margin)
verbatim = super verbatim = super
verbatim.format = :ruby if @section == 'Examples' verbatim.format = :ruby if @section == 'Examples'
@ -164,7 +164,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# #
# Returns an RDoc::Markup::Paragraph. # Returns an RDoc::Markup::Paragraph.
def build_paragraph margin def build_paragraph(margin)
p :paragraph_start => margin if @debug p :paragraph_start => margin if @debug
paragraph = RDoc::Markup::Paragraph.new paragraph = RDoc::Markup::Paragraph.new
@ -204,7 +204,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
## ##
# Detects a section change to "Returns" and adds a heading # Detects a section change to "Returns" and adds a heading
def parse_text parent, indent # :nodoc: def parse_text(parent, indent) # :nodoc:
paragraph = build_paragraph indent paragraph = build_paragraph indent
if false == @seen_returns and 'Returns' == @section then if false == @seen_returns and 'Returns' == @section then
@ -222,7 +222,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# #
# Returns self. # Returns self.
def tokenize text def tokenize(text)
text = text.sub(/\A(Public|Internal|Deprecated):\s+/, '') text = text.sub(/\A(Public|Internal|Deprecated):\s+/, '')
setup_scanner text setup_scanner text

Some files were not shown because too many files have changed in this diff Show more