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

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

Class Method Summary collapse

Class Method Details

.parse(text) ⇒ Object



11
12
13
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
55
# File 'lib/protocol/caldav/ical/parser.rb', line 11

def parse(text)
  if text.nil? || text.strip.empty?
    nil
  else
    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)
      unless parsed
        next
      end

      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
        if current.nil? || !current.name.casecmp?(end_name)
          raise ParseError, "Mismatched END:#{end_name} (expected END:#{current&.name})"
        end

        if stack.empty?
          break
        else
          parent = stack.pop
          parent.components << current
          current = parent
        end
      else
        current&.properties&.push(Property.new(name: name, params: params, value: value))
      end
    end
    if current && stack.any?
      raise ParseError, "Unclosed component: #{current&.name}"
    end
    current
  end
end