class Icalendar::Component
def self.parse(source)
def self.parse(source) _parse source rescue ArgumentError source.rewind if source.respond_to?(:rewind) _parse Parser.clean_bad_wrapping(source) end
def _parse(source)
def _parse(source) = Parser.new(source) .component_class = self .parse
def ical_components
def ical_components collection = [] (self.class.components + custom_components.keys).each do |component_name| components = send component_name components.each do |component| collection << component.to_ical end end collection.empty? ? nil : collection.join.chomp("\r\n") end
def ical_fold(long_line, indent = "\x20")
def ical_fold(long_line, indent = "\x20") # rfc2445 says: # Lines of text SHOULD NOT be longer than 75 octets, excluding the line # break. Long content lines SHOULD be split into a multiple line # representations using a line "folding" technique. That is, a long # line can be split between any two characters by inserting a CRLF # immediately followed by a single linear white space character (i.e., # SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence # of CRLF followed immediately by a single linear white space character # is ignored (i.e., removed) when processing the content type. # # Note the useage of "octets" and "characters": a line should not be longer # than 75 octets, but you need to split between characters, not bytes. # This is challanging with Unicode composing accents, for example. return long_line if long_line.bytesize <= Icalendar::MAX_LINE_LENGTH chars = long_line.scan(ICAL_FOLD_LONG_LINE_SCAN_REGEX) # split in graphenes folded = [''] bytes = 0 while chars.count > 0 c = chars.shift cb = c.bytes.count if bytes + cb > Icalendar::MAX_LINE_LENGTH # Split here folded.push "#{indent}" bytes = indent.bytes.count end folded[-1] += c bytes += cb end folded.join("\r\n") end
def ical_prop_name(prop_name)
def ical_prop_name(prop_name) prop_name.gsub(ICAL_PROP_NAME_GSUB_REGEX, '').gsub('_', '-').upcase end
def ical_properties
def ical_properties (self.class.properties + custom_properties.keys).map do |prop| value = property prop unless value.nil? if value.is_a? ::Array value.map do |part| ical_fold "#{ical_prop_name prop}#{part.to_ical self.class.default_property_types[prop]}" end.join "\r\n" unless value.empty? else ical_fold "#{ical_prop_name prop}#{value.to_ical self.class.default_property_types[prop]}" end end end.compact.join "\r\n" end
def initialize(name, ical_name = nil)
def initialize(name, ical_name = nil) @name = name @ical_name = ical_name || "V#{name.upcase}" super() end
def new_uid
def new_uid SecureRandom.uuid end
def to_ical
def to_ical [ "BEGIN:#{ical_name}", ical_properties, ical_components, "END:#{ical_name}\r\n" ].compact.join "\r\n" end