Class: RDoc::Comment

Inherits:
Object
  • Object
show all
Includes:
Text
Defined in:
lib/rdoc/comment.rb

Constant Summary

Constants included from Text

Text::MARKUP_FORMAT, Text::SPACE_SEPARATED_LETTER_CLASS

Instance Attribute Summary collapse

Attributes included from Text

#language

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Text

decode_legacy_label, expand_tabs, #flush_left, #markup, #normalize_comment, #snippet, #strip_hashes, #strip_newlines, #strip_stars, to_anchor, #wrap

Constructor Details

#initialize(text = nil, location = nil, language = nil) ⇒ Comment

Creates a new comment with text that is found in the RDoc::TopLevel location.



56
57
58
59
60
61
62
63
64
# File 'lib/rdoc/comment.rb', line 56

def initialize(text = nil, location = nil, language = nil)
  @location = location
  @text     = text.nil? ? nil : text.dup
  @language = language

  @document   = nil
  @format     = 'rdoc'
  @normalized = false
end

Instance Attribute Details

#document=(value) ⇒ Object (writeonly)

Overrides the content returned by #parse. Use when there is no #text source for this comment



50
51
52
# File 'lib/rdoc/comment.rb', line 50

def document=(value)
  @document = value
end

#formatObject

The format of this comment. Defaults to RDoc::Markup



19
20
21
# File 'lib/rdoc/comment.rb', line 19

def format
  @format
end

#lineObject

Line where this Comment was written



29
30
31
# File 'lib/rdoc/comment.rb', line 29

def line
  @line
end

#locationObject Also known as: file

The RDoc::TopLevel this comment was found in



24
25
26
# File 'lib/rdoc/comment.rb', line 24

def location
  @location
end

#textObject Also known as: to_s

The text for this comment



39
40
41
# File 'lib/rdoc/comment.rb', line 39

def text
  @text
end

Class Method Details

.from_document(document) ⇒ Object

Create a new parsed comment from a document



181
182
183
184
185
186
# File 'lib/rdoc/comment.rb', line 181

def from_document(document) # :nodoc:
  comment = RDoc::Comment.new('')
  comment.document = document
  comment.location = RDoc::TopLevel.new(document.file) if document.file
  comment
end

.parse(text, filename, line_no, type, &include_callback) ⇒ Object

Parse comment, collect directives as an attribute and return [normalized_comment_text, directives_hash] This method expands include and removes everything not needed in the document text, such as private section, directive line, comment characters ‘# /* * */` and indent spaces.

RDoc comment consists of include, directive, multiline directive, private section and comment text.

Include

# :include: filename

Directive

# :directive-without-value:
# :directive-with-value: value

Multiline directive (only :call-seq:)

# :multiline-directive:
#   value1
#   value2

Private section

#--
# private comment
#++


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/rdoc/comment.rb', line 211

def parse(text, filename, line_no, type, &include_callback)
  case type
  when :ruby
    text = text.gsub(/^#+/, '') if text.start_with?('#')
    private_start_regexp = /^-{2,}$/
    private_end_regexp = /^\+{2}$/
    indent_regexp = /^\s*/
  when :c
    private_start_regexp = /^(\s*\*)?-{2,}$/
    private_end_regexp = /^(\s*\*)?\+{2}$/
    indent_regexp = /^\s*(\/\*+|\*)?\s*/
    text = text.gsub(/\s*\*+\/\s*\z/, '')
  when :simple
    # Unlike other types, this implementation only looks for two dashes at
    # the beginning of the line. Three or more dashes are considered to be
    # a rule and ignored.
    private_start_regexp = /^-{2}$/
    private_end_regexp = /^\+{2}$/
    indent_regexp = /^\s*/
  end

  directives = {}
  lines = text.split("\n")
  in_private = false
  comment_lines = []
  until lines.empty?
    line = lines.shift
    read_lines = 1
    if in_private
      # If `++` appears in a private section that starts with `--`, private section ends.
      in_private = false if line.match?(private_end_regexp)
      line_no += read_lines
      next
    elsif line.match?(private_start_regexp)
      # If `--` appears in a line, private section starts.
      in_private = true
      line_no += read_lines
      next
    end

    prefix = line[indent_regexp]
    prefix_indent = ' ' * prefix.size
    line = line.byteslice(prefix.bytesize..)

    if (directive_match = DIRECTIVE_OR_ESCAPED_DIRECTIV_REGEXP.match(line))
      colon = directive_match[:colon]
      directive = directive_match[:directive]
      raw_param = directive_match[:param]
      param = raw_param.strip
    else
      colon = directive = raw_param = param = nil
    end

    if !directive
      comment_lines << prefix_indent + line
    elsif colon == '\\:'
      # If directive is escaped, unescape it
      comment_lines << prefix_indent + line.sub('\\:', ':')
    elsif raw_param.start_with?(':') || (colon.empty? && !COLON_LESS_DIRECTIVES.include?(directive))
      # Something like `:toto::` is not a directive
      # Only few directives allows to start without a colon
      comment_lines << prefix_indent + line
    elsif directive == 'include'
      filename_to_include = param
      include_callback.call(filename_to_include, prefix_indent).lines.each { |l| comment_lines << l.chomp }
    elsif MULTILINE_DIRECTIVES.include?(directive)
      value_lines = take_multiline_directive_value_lines(directive, filename, line_no, lines, prefix_indent.size, indent_regexp, !param.empty?)
      read_lines += value_lines.size
      lines.shift(value_lines.size)
      unless param.empty?
        # Accept `:call-seq: first-line\n  second-line` for now
        value_lines.unshift(param)
      end
      value = value_lines.join("\n")
      directives[directive] = [value.empty? ? nil : value, line_no]
    else
      directives[directive] = [param.empty? ? nil : param, line_no]
    end
    line_no += read_lines
  end

  normalized_comment = String.new(encoding: text.encoding) << normalize_comment_lines(comment_lines).join("\n")
  [normalized_comment, directives]
end

Instance Method Details

#==(other) ⇒ Object

:nodoc:



74
75
76
77
# File 'lib/rdoc/comment.rb', line 74

def ==(other) # :nodoc:
  self.class === other and
    other.text == @text and other.location == @location
end

#empty?Boolean

A comment is empty if its text String is empty.

Returns:

  • (Boolean)


82
83
84
# File 'lib/rdoc/comment.rb', line 82

def empty?
  @text.empty? && (@document.nil? || @document.empty?)
end

#encode!(encoding) ⇒ Object

HACK dubious



89
90
91
92
# File 'lib/rdoc/comment.rb', line 89

def encode!(encoding)
  @text = String.new @text, encoding: encoding
  self
end

#initialize_copy(copy) ⇒ Object

– TODO deep copy @document



70
71
72
# File 'lib/rdoc/comment.rb', line 70

def initialize_copy(copy) # :nodoc:
  @text = copy.text.dup
end

#inspectObject

:nodoc:



102
103
104
105
106
# File 'lib/rdoc/comment.rb', line 102

def inspect # :nodoc:
  location = @location ? @location.relative_name : '(unknown)'

  "#<%s:%x %s %p>" % [self.class, object_id, location, @text]
end

#normalizeObject

Normalizes the text. See RDoc::Text#normalize_comment for details



111
112
113
114
115
116
117
118
119
120
# File 'lib/rdoc/comment.rb', line 111

def normalize
  return self unless @text
  return self if @normalized # TODO eliminate duplicate normalization

  @text = normalize_comment @text

  @normalized = true

  self
end

#normalized=(value) ⇒ Object

Change normalized, when creating already normalized comment.



124
125
126
# File 'lib/rdoc/comment.rb', line 124

def normalized=(value)
  @normalized = value
end

#normalized?Boolean

Was this text normalized?

Returns:

  • (Boolean)


131
132
133
# File 'lib/rdoc/comment.rb', line 131

def normalized? # :nodoc:
  @normalized
end

#parseObject

Parses the comment into an RDoc::Markup::Document. The parsed document is cached until the text is changed.



139
140
141
142
143
144
145
# File 'lib/rdoc/comment.rb', line 139

def parse
  return @document if @document

  @document = super @text, @format
  @document.file = @location
  @document
end

#tomdoc?Boolean

Returns true if this comment is in TomDoc format.

Returns:

  • (Boolean)


163
164
165
# File 'lib/rdoc/comment.rb', line 163

def tomdoc?
  @format == 'tomdoc'
end