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.



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

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



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

def document=(value)
  @document = value
end

#format ⇒ Object

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



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

def format
  @format
end

#line ⇒ Object

Line where this Comment was written



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

def line
  @line
end

#location ⇒ Object Also known as: file

The RDoc::TopLevel this comment was found in



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

def location
  @location
end

#text ⇒ Object Also known as: to_s

The text for this comment



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

def text
  @text
end

Class Method Details

.from_document(document) ⇒ Object

Create a new parsed comment from a document



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

def from_document(document) # :nodoc:
  comment = Comment.new('')
  comment.document = document
  comment.location = 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

#++



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
295
# File 'lib/rdoc/comment.rb', line 212

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:



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

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)


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

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

#encode!(encoding) ⇒ Object

HACK dubious



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

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

#initialize_copy(copy) ⇒ Object

-- TODO deep copy @document



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

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

#inspect ⇒ Object

:nodoc:



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

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

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

#normalize ⇒ Object

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



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

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.



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

def normalized=(value)
  @normalized = value
end

#normalized? ⇒ Boolean

Was this text normalized?

Returns:

  • (Boolean)


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

def normalized? # :nodoc:
  @normalized
end

#parse ⇒ Object

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



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

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)


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

def tomdoc?
  @format == 'tomdoc'
end