class Erudite::Extractor

Extracts examples from comments.

Public Class Methods

extract(source) click to toggle source
# File lib/erudite/extractor.rb, line 8
def self.extract(source)
  group_comments(parse_comments(source))
    .map { |group| group.flat_map { |comment| extract_text(comment) } }
    .map { |text| find_examples(group_text(text)).join("\n") }
    .reject(&:empty?)
    .map { |example| Example::Parser.parse(example) }
end
extract_text(comment) click to toggle source
# File lib/erudite/extractor.rb, line 38
def self.extract_text(comment)
  if comment.inline?
    [comment.text[1..-1]]
  else
    comment.text[7..-6].lines.map(&:chomp)
  end
end
find_examples(groups) click to toggle source
# File lib/erudite/extractor.rb, line 16
def self.find_examples(groups)
  groups
    .reject(&:empty?)
    .each_with_object([]) do |lines, examples|
      lines.first.match(/^(\s*)>> /) do |match|
        if lines.all? { |line| line.start_with?(match[1]) }
          examples.push(lines.map { |line| line[match[1].size..-1] })
        end
      end
    end
end
group_comments(comments) click to toggle source
# File lib/erudite/extractor.rb, line 46
def self.group_comments(comments)
  previous = comments.first

  comments.each_with_object([]) do |comment, groups|
    groups.push([]) unless groupable?(previous, comment)
    groups.last.push(comment)
    previous = comment
  end
end
group_text(lines) click to toggle source
# File lib/erudite/extractor.rb, line 28
def self.group_text(lines)
  lines.each_with_object([[]]) do |line, groups|
    if line[/^\s*$/]
      groups.push([])
    else
      groups.last.push(line.chomp)
    end
  end
end
groupable?(a, b) click to toggle source
# File lib/erudite/extractor.rb, line 56
def self.groupable?(a, b)
  a.loc.line == b.loc.line - 1 &&
    a.loc.column == b.loc.column
end
parse_comments(source) click to toggle source
# File lib/erudite/extractor.rb, line 61
def self.parse_comments(source)
  Parser::CurrentRuby.parse_with_comments(source).last
end