class Norma43::Parser

Attributes

file[R]

Public Class Methods

new(file) click to toggle source

Parser.new accepts a File instance or a String A InvalidFileFormatError will be raised if file isn’t in the Norma43 format

# File lib/norma43/parser.rb, line 11
def initialize(file)
  @file = file
  validator = validate_file_format
  @contexts = if validator.has_document?
    Norma43::Utils::Contexts.new
  else
    # in theory Norma43 says that files should start with DocumentStart but
    # practically doesn't happen, so that we create one artificially
    # to avoid corner cases in the processors
    Norma43::Utils::Contexts.new().tap { |ctx| ctx.add Models::Document.new }
  end
end

Public Instance Methods

result() click to toggle source
# File lib/norma43/parser.rb, line 24
def result
  parse_lines(@contexts).result
end

Protected Instance Methods

lines() click to toggle source
# File lib/norma43/parser.rb, line 29
def lines
  @lines ||= file.each_line
end

Private Instance Methods

encode_lines?() click to toggle source
# File lib/norma43/parser.rb, line 62
def encode_lines?
  first_line.encoding != Encoding::UTF_8
end
first_line() click to toggle source
# File lib/norma43/parser.rb, line 66
def first_line
  @first_line ||= begin
    line = self.lines.peek
    self.lines.rewind # peek seems to move the pointer when file is an actual File object

    line
  end
end
handler_for_line(line) click to toggle source
# File lib/norma43/parser.rb, line 58
def handler_for_line(line)
  LineHandlers.mapping.fetch line[0..1]
end
parse_line(line, contexts) click to toggle source

Look up a matching handler for the line and process it The process method on a handler always returns a Contexts object

# File lib/norma43/parser.rb, line 50
def parse_line(line, contexts)
  line = line.encode Encoding::UTF_8 if encode_lines?

  handler = handler_for_line line

  handler.process line, contexts
end
parse_lines(contexts) click to toggle source
# File lib/norma43/parser.rb, line 40
def parse_lines(contexts)
  parse_lines parse_line(self.lines.next, contexts)

rescue StopIteration # because lines is an enumerator raises StopIteration on end
  self.lines.rewind # Ensure we do not bomb out when calling result multiple times
  contexts
end
validate_file_format() click to toggle source
# File lib/norma43/parser.rb, line 34
def validate_file_format
  validator = Norma43::LineParsers::FileFormatValidator.new first_line
  raise InvalidFileFormatError.new(validator.errors.join(", ")) unless validator.valid?
  validator
end