Module: Protocol::Caldav::Ical::Parser

Defined in:
lib/protocol/caldav/ical/parser.rb

Class Method Summary collapse

Class Method Details

.parse(text) ⇒ Object

Raises:



14
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
54
# File 'lib/protocol/caldav/ical/parser.rb', line 14

def parse(text)
  return nil if text.nil? || text.strip.empty?

  # Strip BOM
  text = text.sub(/\A\xEF\xBB\xBF/, '')

  lines = ContentLine.unfold(text).split("\n").map(&:strip).reject(&:empty?)
  stack = []
  current = nil

  lines.each do |line|
    parsed = ContentLine.parse_line(line)
    next unless parsed

    name, params, value = parsed

    if name.casecmp?('BEGIN')
      comp = Component.new(name: value.strip.upcase)
      if current
        stack.push(current)
      end
      current = comp
    elsif name.casecmp?('END')
      end_name = value.strip.upcase
      raise ParseError, "Mismatched END:#{end_name} (expected END:#{current&.name})" if current.nil? || !current.name.casecmp?(end_name)

      if stack.empty?
        return current
      else
        parent = stack.pop
        parent.components << current
        current = parent
      end
    else
      current&.properties&.push(Property.new(name: name, params: params, value: value))
    end
  end

  raise ParseError, "Unclosed component: #{current&.name}" if current && stack.any?
  current
end