mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 df7dac9174
			
		
	
	
		df7dac9174
		
	
	
	
	
		
			
			RDoc 4.1.0 contains a number of enhancements including a new default style and accessibility support. You can see the changelog here: https://github.com/rdoc/rdoc/blob/v4.1.0.preview.1/History.rdoc * test/rdoc: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42971 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			229 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| ##
 | |
| # A comment holds the text comment for a RDoc::CodeObject and provides a
 | |
| # unified way of cleaning it up and parsing it into an RDoc::Markup::Document.
 | |
| #
 | |
| # Each comment may have a different markup format set by #format=.  By default
 | |
| # 'rdoc' is used.  The :markup: directive tells RDoc which format to use.
 | |
| #
 | |
| # See RDoc::Markup@Other+directives for instructions on adding an alternate
 | |
| # format.
 | |
| 
 | |
| class RDoc::Comment
 | |
| 
 | |
|   include RDoc::Text
 | |
| 
 | |
|   ##
 | |
|   # The format of this comment.  Defaults to RDoc::Markup
 | |
| 
 | |
|   attr_reader :format
 | |
| 
 | |
|   ##
 | |
|   # The RDoc::TopLevel this comment was found in
 | |
| 
 | |
|   attr_accessor :location
 | |
| 
 | |
|   ##
 | |
|   # For duck-typing when merging classes at load time
 | |
| 
 | |
|   alias file location # :nodoc:
 | |
| 
 | |
|   ##
 | |
|   # The text for this comment
 | |
| 
 | |
|   attr_reader :text
 | |
| 
 | |
|   ##
 | |
|   # Overrides the content returned by #parse.  Use when there is no #text
 | |
|   # source for this comment
 | |
| 
 | |
|   attr_writer   :document
 | |
| 
 | |
|   ##
 | |
|   # Creates a new comment with +text+ that is found in the RDoc::TopLevel
 | |
|   # +location+.
 | |
| 
 | |
|   def initialize text = nil, location = nil
 | |
|     @location = location
 | |
|     @text     = text
 | |
| 
 | |
|     @document   = nil
 | |
|     @format     = 'rdoc'
 | |
|     @normalized = false
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   #--
 | |
|   # TODO deep copy @document
 | |
| 
 | |
|   def initialize_copy copy # :nodoc:
 | |
|     @text = copy.text.dup
 | |
|   end
 | |
| 
 | |
|   def == other # :nodoc:
 | |
|     self.class === other and
 | |
|       other.text == @text and other.location == @location
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Look for a 'call-seq' in the comment to override the normal parameter
 | |
|   # handling.  The :call-seq: is indented from the baseline.  All lines of the
 | |
|   # same indentation level and prefix are consumed.
 | |
|   #
 | |
|   # For example, all of the following will be used as the :call-seq:
 | |
|   #
 | |
|   #   # :call-seq:
 | |
|   #   #   ARGF.readlines(sep=$/)     -> array
 | |
|   #   #   ARGF.readlines(limit)      -> array
 | |
|   #   #   ARGF.readlines(sep, limit) -> array
 | |
|   #   #
 | |
|   #   #   ARGF.to_a(sep=$/)     -> array
 | |
|   #   #   ARGF.to_a(limit)      -> array
 | |
|   #   #   ARGF.to_a(sep, limit) -> array
 | |
| 
 | |
|   def extract_call_seq method
 | |
|     # we must handle situations like the above followed by an unindented first
 | |
|     # 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
 | |
|     # paragraph.
 | |
|     if @text =~ /^\s*:?call-seq:(.*?(?:\S).*?)^\s*$/m then
 | |
|       all_start, all_stop = $~.offset(0)
 | |
|       seq_start, seq_stop = $~.offset(1)
 | |
| 
 | |
|       # we get the following lines that start with the leading word at the
 | |
|       # same indent, even if they have blank lines before
 | |
|       if $1 =~ /(^\s*\n)+^(\s*\w+)/m then
 | |
|         leading = $2 # ' *    ARGF' in the example above
 | |
|         re = %r%
 | |
|           \A(
 | |
|              (^\s*\n)+
 | |
|              (^#{Regexp.escape leading}.*?\n)+
 | |
|             )+
 | |
|           ^\s*$
 | |
|         %xm
 | |
| 
 | |
|         if @text[seq_stop..-1] =~ re then
 | |
|           all_stop = seq_stop + $~.offset(0).last
 | |
|           seq_stop = seq_stop + $~.offset(1).last
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       seq = @text[seq_start..seq_stop]
 | |
|       seq.gsub!(/^\s*(\S|\n)/m, '\1')
 | |
|       @text.slice! all_start...all_stop
 | |
| 
 | |
|       method.call_seq = seq.chomp
 | |
| 
 | |
|     elsif @text.sub!(/^\s*:?call-seq:(.*?)(^\s*$|\z)/m, '') then
 | |
|       seq = $1
 | |
|       seq.gsub!(/^\s*/, '')
 | |
|       method.call_seq = seq
 | |
|     end
 | |
| 
 | |
|     method
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # A comment is empty if its text String is empty.
 | |
| 
 | |
|   def empty?
 | |
|     @text.empty?
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # HACK dubious
 | |
| 
 | |
|   def force_encoding encoding
 | |
|     @text.force_encoding encoding
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Sets the format of this comment and resets any parsed document
 | |
| 
 | |
|   def format= format
 | |
|     @format = format
 | |
|     @document = nil
 | |
|   end
 | |
| 
 | |
|   def inspect # :nodoc:
 | |
|     location = @location ? @location.relative_name : '(unknown)'
 | |
| 
 | |
|     "#<%s:%x %s %p>" % [self.class, object_id, location, @text]
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Normalizes the text.  See RDoc::Text#normalize_comment for details
 | |
| 
 | |
|   def normalize
 | |
|     return self unless @text
 | |
|     return self if @normalized # TODO eliminate duplicate normalization
 | |
| 
 | |
|     @text = normalize_comment @text
 | |
| 
 | |
|     @normalized = true
 | |
| 
 | |
|     self
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Was this text normalized?
 | |
| 
 | |
|   def normalized? # :nodoc:
 | |
|     @normalized
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Parses the comment into an RDoc::Markup::Document.  The parsed document is
 | |
|   # cached until the text is changed.
 | |
| 
 | |
|   def parse
 | |
|     return @document if @document
 | |
| 
 | |
|     @document = super @text, @format
 | |
|     @document.file = @location
 | |
|     @document
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Removes private sections from this comment.  Private sections are flush to
 | |
|   # the comment marker and start with <tt>--</tt> and end with <tt>++</tt>.
 | |
|   # For C-style comments, a private marker may not start at the opening of the
 | |
|   # comment.
 | |
|   #
 | |
|   #   /*
 | |
|   #    *--
 | |
|   #    * private
 | |
|   #    *++
 | |
|   #    * public
 | |
|   #    */
 | |
| 
 | |
|   def remove_private
 | |
|     # Workaround for gsub encoding for Ruby 1.9.2 and earlier
 | |
|     empty = ''
 | |
|     empty.force_encoding @text.encoding if Object.const_defined? :Encoding
 | |
| 
 | |
|     @text = @text.gsub(%r%^\s*([#*]?)--.*?^\s*(\1)\+\+\n?%m, empty)
 | |
|     @text = @text.sub(%r%^\s*[#*]?--.*%m, '')
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Replaces this comment's text with +text+ and resets the parsed document.
 | |
|   #
 | |
|   # An error is raised if the comment contains a document but no text.
 | |
| 
 | |
|   def text= text
 | |
|     raise RDoc::Error, 'replacing document-only comment is not allowed' if
 | |
|       @text.nil? and @document
 | |
| 
 | |
|     @document = nil
 | |
|     @text = text
 | |
|   end
 | |
| 
 | |
|   ##
 | |
|   # Returns true if this comment is in TomDoc format.
 | |
| 
 | |
|   def tomdoc?
 | |
|     @format == 'tomdoc'
 | |
|   end
 | |
| 
 | |
| end
 | |
| 
 |