class Enolib::Reporter

Public Class Methods

new(context) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 5
def initialize(context)
  @context = context
  @index = Array.new(@context.line_count)
  @snippet = Array.new(@context.line_count)

  build_index
end

Public Instance Methods

indicate_line(element) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 13
def indicate_line(element)
  @snippet[element[:line]] = :indicate
  self
end
question_line(element) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 18
def question_line(element)
  @snippet[element[:line]] = :question
  self
end
report_comments(element) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 23
def report_comments(element)
  @snippet[element[:line]] = :indicate
  element[:comments].each do |comment|
    @snippet[comment[:line]] = :emphasize
  end

  self
end
report_element(element) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 32
def report_element(element)
  @snippet[element[:line]] = :emphasize
  tag_children(element, :indicate)

  self
end
report_elements(elements) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 39
def report_elements(elements)
  elements.each do |element|
    @snippet[element[:line]] = :emphasize
    tag_children(element, :indicate)
  end

  self
end
report_line(instruction) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 48
def report_line(instruction)
  @snippet[instruction[:line]] = :emphasize

  self
end
report_missing_element(parent) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 62
def report_missing_element(parent)
  @snippet[parent[:line]] = :indicate unless parent[:type] == :document

  if parent[:type] == :section
    tag_section(parent, :question, false)
  else
    tag_children(parent, :question)
  end

  self
end
report_multiline_value(element) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 54
def report_multiline_value(element)
  element[:lines].each do |line|
    @snippet[line[:line]] = :emphasize
  end

  self
end
snippet() click to toggle source
# File lib/enolib/reporters/reporter.rb, line 74
def snippet
  if @snippet.none?
    (0...@snippet.length).each do |line|
      @snippet[line] = :question
    end
  else
    # TODO: Possibly better algorithm for this
    @snippet.each_with_index do |tag, line|
      next if tag

      if line + 2 < @context.line_count && @snippet[line + 2] && @snippet[line + 2] != :display ||
         line - 2 > 0 && @snippet[line - 2] && @snippet[line - 2] != :display ||
         line + 1 < @context.line_count && @snippet[line + 1] && @snippet[line + 1] != :display ||
         line - 1 > 0 && @snippet[line - 1] && @snippet[line - 1] != :display
        @snippet[line] = :display
      elsif line + 3 < @context.line_count && @snippet[line + 3] && @snippet[line + 3] != :display
        @snippet[line] = :omission
      end
    end

    @snippet[-1] = :omission unless @snippet[-1]
  end

  print
end

Private Instance Methods

build_index() click to toggle source
# File lib/enolib/reporters/reporter.rb, line 167
def build_index
  traverse(@context.document)

  @context.meta.each do |instruction|
    @index[instruction[:line]] = instruction
  end
end
index_comments(element) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 102
def index_comments(element)
  return unless element.has_key?(:comments)

  element[:comments].each do |comment|
    @index[comment[:line]] = comment
  end
end
tag_children(element, tag) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 212
def tag_children(element, tag)
  case element[:type]
  when :field, :list_item, :fieldset_entry
    return tag_continuations(element, tag)
  when :list
    return tag_continuables(element, :items, tag)
  when :fieldset
    return tag_continuables(element, :entries, tag)
  when :multiline_field_begin
    if element.has_key?(:lines)
      element[:lines].each do |line|
        @snippet[line[:line]] = tag
      end
    end

    if element.has_key?(:end)
      @snippet[element[:end][:line]] = tag
      return element[:end][:line] + 1
    end

    return element[:lines][-1][:line] + 1 if element.has_key?(:lines)
    return element[:line] + 1
  when :section
    return tag_section(element, tag)
  end
end
tag_continuables(element, collection, tag) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 193
def tag_continuables(element, collection, tag)
  scan_line = element[:line] + 1

  return scan_line unless element.has_key?(collection)

  element[collection].each do |continuable|
    while scan_line < continuable[:line]
      @snippet[scan_line] = tag
      scan_line += 1
    end

    @snippet[continuable[:line]] = tag

    scan_line = tag_continuations(continuable, tag)
  end

  scan_line
end
tag_continuations(element, tag) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 175
def tag_continuations(element, tag)
  scan_line = element[:line] + 1

  return scan_line unless element.has_key?(:continuations)

  element[:continuations].each do |continuation|
    while scan_line < continuation[:line]
      @snippet[scan_line] = tag
      scan_line += 1
    end

    @snippet[continuation[:line]] = tag
    scan_line += 1
  end

  scan_line
end
tag_section(section, tag, recursive = true) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 239
def tag_section(section, tag, recursive = true)
  scan_line = section[:line] + 1

  section[:elements].each do |element|
    while scan_line < element[:line]
      @snippet[scan_line] = tag
      scan_line += 1
    end

    break if element[:type] == :section && !recursive

    @snippet[element[:line]] = tag

    scan_line = tag_children(element, tag)
  end

  scan_line
end
traverse(section) click to toggle source
# File lib/enolib/reporters/reporter.rb, line 110
def traverse(section)
  section[:elements].each do |element|
    index_comments(element)

    @index[element[:line]] = element

    if element[:type] == :section
      traverse(element)
    elsif element[:type] == :field
      if element.has_key?(:continuations)
        element[:continuations].each do |continuation|
          @index[continuation[:line]] = continuation
        end
      end
    elsif element[:type] == :multiline_field_begin
      # Missing when reporting an unterminated multiline field
      if element.has_key?(:end)
        @index[element[:end][:line]] = element[:end]
      end

      if element.has_key?(:lines)
        element[:lines].each do |line|
          @index[line[:line]] = line
        end
      end
    elsif element[:type] == :list
      if element.has_key?(:items)
        element[:items].each do |item|
          index_comments(item)

          @index[item[:line]] = item

          next unless item.has_key?(:continuations)

          item[:continuations].each do |continuation|
            @index[continuation[:line]] = continuation
          end
        end
      end
    elsif element[:type] == :fieldset
      if element.has_key?(:entries)
        element[:entries].each do |entry|
          index_comments(entry)

          @index[entry[:line]] = entry

          next unless entry.has_key?(:continuations)

          entry[:continuations].each do |continuation|
            @index[continuation[:line]] = continuation
          end
        end
      end
    end
  end
end