Class: RubyDocTest::Lines

Inherits:
Object
  • Object
show all
Defined in:
lib/lines.rb

Overview

Description

Keeps track of which lines within a document belong to a group. Line groups are determined by their indentation level, as in the Python programming language.

Example

This line and the next one
  are part of the same group

But this line is separate from
this line.

Note

This class also considers one '#' character (comment) as an indentation character, i.e. similar to how whitespace is treated.

Direct Known Subclasses

Result, SpecialDirective, Statement

Instance Method Summary collapse

Constructor Details

#initialize(doc_lines, line_index = 0) ⇒ Lines

Returns a new instance of Lines.


17
18
19
# File 'lib/lines.rb', line 17

def initialize(doc_lines, line_index = 0)
  @doc_lines, @line_index = doc_lines, line_index
end

Instance Method Details

#inspectObject


94
95
96
# File 'lib/lines.rb', line 94

def inspect
  "#<#{self.class} lines=#{lines.inspect}>"
end

#line_numberObject


22
23
24
# File 'lib/lines.rb', line 22

def line_number
  @line_index + 1
end

#linesObject

Tests

doctest: Return an array of 1 line if there is only one line >> l = RubyDocTest::Lines.new([“line 1”]) >> l.lines

> [“line 1”]

doctest: Remove indentation from lines 2 to the end of this Lines group. >> l = RubyDocTest::Lines.new([“line 1”, “ line 2”, “ line 3”, “ line 4”]) >> l.lines

> [“line 1”, “line 2”, “line 3”, “ line 4”]


36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/lines.rb', line 36

def lines
  r = range
  size = r.last - r.first + 1
  if size > 1
    # Remove indentation from all lines after the first,
    # as measured from the 2nd line's indentation level
    idt2 = indentation(@doc_lines, @line_index + 1)
    [@doc_lines[range.first]] +
    @doc_lines[(range.first + 1)..(range.last)].
      map{ |l| $1 if l =~ /^#{Regexp.escape(idt2)}(.*)/ }
  else
    @doc_lines[range]
  end
end

#range(doc_lines = @doc_lines, start_index = @line_index) ⇒ Object

Description

Calculate the range of python-like indentation within this Lines group

Tests

>> l = RubyDocTest::Lines.new([])

doctest: Return a range of one line when there is only one line to begin with >> l.range %w(a), 0

> 0..0

doctest: Return a range of one line when there are two lines, side by side >> l.range %w(a b), 0

> 0..0

>> l.range %w(a b), 1

> 1..1

doctest: Return a range of two lines when there are two lines, the second blank >> l.range [“a”, “”], 0

> 0..1

doctest: Return a range of two lines when the second is indented >> l.range [“a”, “ b”], 0

> 0..1

doctest: Indentation can also include the ?> marker >> l.range [“>> 1 +”, “?> 2”], 0

> 0..1


79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/lines.rb', line 79

def range(doc_lines = @doc_lines, start_index = @line_index)
  end_index = start_index
  idt = indentation(doc_lines, start_index)
  # Find next lines that are blank, or have indentation more than the first line
  remaining_lines(doc_lines, start_index + 1).each do |current_line|
    if current_line =~ /^(#{Regexp.escape(idt)}(\s+|\?>\s)|\s*$)/
      end_index += 1
    else
      break
    end
  end
  # Compute the range from what we found
  start_index..end_index
end