Class: Deb822::Scanner

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

Overview

Low-level parser for deb822 documents

Constant Summary collapse

WS =
/[ \t]/

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Scanner

Returns a new instance of Scanner.



7
8
9
10
11
# File 'lib/deb822/scanner.rb', line 7

def initialize(input)
  @input = input.is_a?(String) ? StringIO.new(input) : input

  @in_paragraph = false
end

Instance Method Details

#each_lineObject Also known as: lines



55
56
57
58
59
60
61
# File 'lib/deb822/scanner.rb', line 55

def each_line
  return to_enum(:each_line) unless block_given?

  while l = next_line
    yield l
  end
end

#next_lineObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/deb822/scanner.rb', line 15

def next_line
  loop do
    begin
      line = @input.readline
    rescue EOFError
      break
    end

    case line
    when /\A#{WS}*\Z/o
      # > The paragraphs are separated by empty lines.
      # > Parsers may accept lines consisting solely of U+0020 SPACE and U+0009 TAB as paragraph separators
      if @in_paragraph
        @in_paragraph = false
        break [:paragraph_separator]
      else
        next
      end
    when /\A#/
      # > Lines starting with U+0023 ‘#’, without any preceding whitespace are comments lines
      break [:comment, $']
    when /\A(#{FieldName::PATTERN}):#{WS}*/o
      name = $1
      value = $'.chomp
      @in_paragraph = true
      break [:field, name, value]
    when /\A#{WS}\.?/o
      # > The lines after the first are called continuation lines and must start with a U+0020 SPACE or a U+0009 TAB.
      # > Empty lines in field values are usually escaped by representing them by a U+0020 SPACE followed
      # > by a dot (U+002E ‘.’).
      raise FormatError, "Unexpected continuation line: #{line.inspect}" unless @in_paragraph
      break [:continuation, $']
    else
      raise FormatError, "Ill-formed line: #{line.inspect}"
    end

    return nil
  end
end