icalendar 0.95 → 0.96

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/README +9 -4
  2. data/Rakefile +4 -3
  3. data/docs/examples/parse_cal.rb +1 -1
  4. data/lib/icalendar/calendar.rb +15 -51
  5. data/lib/icalendar/component.rb +75 -21
  6. data/lib/icalendar/component/event.rb +60 -11
  7. data/lib/icalendar/component/timezone.rb +31 -7
  8. data/lib/icalendar/component/todo.rb +1 -1
  9. data/lib/icalendar/conversions.rb +3 -1
  10. data/lib/icalendar/foo.rb +394 -0
  11. data/lib/icalendar/parser.rb +29 -22
  12. data/test/calendar_test.rb +37 -37
  13. data/test/component/event_test.rb +1 -1
  14. data/test/component_test.rb +56 -56
  15. data/test/interactive.rb +15 -0
  16. data/test/life.ics +45 -0
  17. data/test/parameter_test.rb +20 -0
  18. metadata +23 -70
  19. data/docs/api/classes/Array.html +0 -146
  20. data/docs/api/classes/Date.html +0 -157
  21. data/docs/api/classes/DateTime.html +0 -178
  22. data/docs/api/classes/Fixnum.html +0 -146
  23. data/docs/api/classes/Float.html +0 -146
  24. data/docs/api/classes/Icalendar/Alarm.html +0 -184
  25. data/docs/api/classes/Icalendar/Base.html +0 -118
  26. data/docs/api/classes/Icalendar/Calendar.html +0 -411
  27. data/docs/api/classes/Icalendar/Component.html +0 -306
  28. data/docs/api/classes/Icalendar/DateProp.html +0 -187
  29. data/docs/api/classes/Icalendar/DateProp/ClassMethods.html +0 -195
  30. data/docs/api/classes/Icalendar/Event.html +0 -202
  31. data/docs/api/classes/Icalendar/Freebusy.html +0 -157
  32. data/docs/api/classes/Icalendar/InvalidComponentClass.html +0 -117
  33. data/docs/api/classes/Icalendar/InvalidPropertyValue.html +0 -117
  34. data/docs/api/classes/Icalendar/Journal.html +0 -190
  35. data/docs/api/classes/Icalendar/Parameter.html +0 -166
  36. data/docs/api/classes/Icalendar/Parser.html +0 -447
  37. data/docs/api/classes/Icalendar/Timezone.html +0 -197
  38. data/docs/api/classes/Icalendar/Todo.html +0 -199
  39. data/docs/api/classes/String.html +0 -160
  40. data/docs/api/classes/Time.html +0 -161
  41. data/docs/api/created.rid +0 -1
  42. data/docs/api/files/COPYING.html +0 -163
  43. data/docs/api/files/GPL.html +0 -531
  44. data/docs/api/files/README.html +0 -241
  45. data/docs/api/files/lib/icalendar/base_rb.html +0 -108
  46. data/docs/api/files/lib/icalendar/calendar_rb.html +0 -101
  47. data/docs/api/files/lib/icalendar/component/alarm_rb.html +0 -101
  48. data/docs/api/files/lib/icalendar/component/event_rb.html +0 -101
  49. data/docs/api/files/lib/icalendar/component/freebusy_rb.html +0 -101
  50. data/docs/api/files/lib/icalendar/component/journal_rb.html +0 -101
  51. data/docs/api/files/lib/icalendar/component/timezone_rb.html +0 -101
  52. data/docs/api/files/lib/icalendar/component/todo_rb.html +0 -101
  53. data/docs/api/files/lib/icalendar/component_rb.html +0 -101
  54. data/docs/api/files/lib/icalendar/conversions_rb.html +0 -108
  55. data/docs/api/files/lib/icalendar/helpers_rb.html +0 -101
  56. data/docs/api/files/lib/icalendar/parameter_rb.html +0 -101
  57. data/docs/api/files/lib/icalendar/parser_rb.html +0 -109
  58. data/docs/api/files/lib/icalendar_rb.html +0 -118
  59. data/docs/api/fr_class_index.html +0 -48
  60. data/docs/api/fr_file_index.html +0 -43
  61. data/docs/api/fr_method_index.html +0 -63
  62. data/docs/api/index.html +0 -24
  63. data/docs/api/rdoc-style.css +0 -208
  64. data/lib/icalendar/#helpers.rb# +0 -92
@@ -164,18 +164,25 @@ module Icalendar
164
164
  break
165
165
  elsif name == "BEGIN" # New component
166
166
  case(fields[:value])
167
- when "VEVENT"
168
- component.events << parse_component(Event.new)
169
- when "VTODO"
170
- component.todos << parse_component(Todo.new)
171
- when "VJOURNAL"
172
- component.journals << parse_component(Journal.new)
173
- when "VFREEBUSY"
174
- component.freebusys << parse_component(Freebusy.new)
175
- when "VTIMEZONE"
176
- component.timezones << parse_component(Timezone.new)
177
- when "VALARM"
178
- component.alarms << parse_component(Alarm.new)
167
+ when "VEVENT" # Event
168
+ component.add_component parse_component(Event.new)
169
+ when "VTODO" # Todo entry
170
+ component.add_component parse_component(Todo.new)
171
+ when "VALARM" # Alarm sub-component for event and todo
172
+ component.add_component parse_component(Alarm.new)
173
+ when "VJOURNAL" # Journal entry
174
+ component.add_component parse_component(Journal.new)
175
+ when "VFREEBUSY" # Free/Busy section
176
+ component.add_component parse_component(Freebusy.new)
177
+ when "VTIMEZONE" # Timezone specification
178
+ component.add_component parse_component(Timezone.new)
179
+ when "STANDARD" # Standard time sub-component for timezone
180
+ component.add_component parse_component(Standard.new)
181
+ when "DAYLIGHT" # Daylight time sub-component for timezone
182
+ component.add_component parse_component(Daylight.new)
183
+ else # Uknown component type, skip to matching end
184
+ until ((line = next_line) == "END:#{fields[:value]}"); end
185
+ next
179
186
  end
180
187
  else # If its not a component then it should be a property
181
188
 
@@ -191,11 +198,11 @@ module Icalendar
191
198
  val = fields[:value]
192
199
  end
193
200
 
194
- if component.multi_property?(name.upcase) && component.properties
201
+ if component.multi_property?(name.upcase)
195
202
  val = [val]
196
203
 
197
204
  if fields[:params].empty?
198
- params = [nil]
205
+ params = []
199
206
  else
200
207
  params = fields[:params]
201
208
  end
@@ -231,21 +238,17 @@ module Icalendar
231
238
  paramslist = $2
232
239
  value = $3
233
240
 
241
+ # Parse the parameters
234
242
  params = {}
235
-
236
- # Collect the params, if any.
237
243
  if paramslist.size > 1
238
-
239
- # v3.0 and v2.1 params
240
244
  paramslist.scan( %r{#{PARAM}}i ) do
241
245
 
242
- # param names are case-insensitive, and multi-valued
246
+ # parameter names are case-insensitive, and multi-valued
243
247
  pname = $1
244
248
  pvals = $3
245
249
 
246
- # v2.1 pvals have no '=' sign, figure out what kind of param it
247
- # is (either its a known encoding, or we treat it as a 'type'
248
- # param).
250
+ # If their isn't an '=' sign then we need to do some custom
251
+ # business. Defaults to 'type'
249
252
  if $2 == ""
250
253
  pvals = $1
251
254
  case $1
@@ -260,9 +263,13 @@ module Icalendar
260
263
  end
261
264
  end
262
265
 
266
+ # Make entries into the params dictionary where the name
267
+ # is the key and the value is an array of values.
263
268
  unless params.key? pname
264
269
  params[pname] = []
265
270
  end
271
+
272
+ # Save all the values into the array.
266
273
  pvals.scan( %r{(#{PVALUE})} ) do
267
274
  if $1.size > 0
268
275
  params[pname] << $1
@@ -6,41 +6,41 @@ require 'icalendar'
6
6
  require 'date'
7
7
 
8
8
  class TestCalendar < Test::Unit::TestCase
9
- # Generate a calendar using the raw api, and then spit it out
10
- # as a string. Parse the string and make sure everything matches up.
11
- def test_raw_generation
12
- # Create a fresh calendar
13
- cal = Icalendar::Calendar.new
14
-
15
- cal.calscale = "GREGORIAN"
16
- cal.version = "3.2"
17
- cal.prodid = "test-prodid"
18
-
19
- # Now generate the string and then parse it so we can verify
20
- # that everything was set, generated and parsed correctly.
21
- calString = cal.to_ical
22
-
23
- cals = Icalendar::Parser.new(calString).parse
24
-
25
- cal2 = cals.first
26
- assert_equal("GREGORIAN", cal2.calscale)
27
- assert_equal("3.2", cal2.version)
28
- assert_equal("test-prodid", cal2.prodid)
29
- end
30
-
31
- def test_block_creation
32
- cal = Icalendar::Calendar.new
33
- cal.event do
34
- dtend "19970903T190000Z"
35
- summary "This is my summary"
36
- end
37
-
38
- event = cal.event
39
- event.dtend = "19970903T190000Z"
40
- event.summary = "This is my summary"
41
-
42
- ev = cal.events.each do |ev|
43
- assert_equal("19970903T190000Z", ev.dtend)
44
- end
45
- end
9
+ # Generate a calendar using the raw api, and then spit it out
10
+ # as a string. Parse the string and make sure everything matches up.
11
+ def test_raw_generation
12
+ # Create a fresh calendar
13
+ cal = Icalendar::Calendar.new
14
+
15
+ cal.calscale = "GREGORIAN"
16
+ cal.version = "3.2"
17
+ cal.prodid = "test-prodid"
18
+
19
+ # Now generate the string and then parse it so we can verify
20
+ # that everything was set, generated and parsed correctly.
21
+ calString = cal.to_ical
22
+
23
+ cals = Icalendar::Parser.new(calString).parse
24
+
25
+ cal2 = cals.first
26
+ assert_equal("GREGORIAN", cal2.calscale)
27
+ assert_equal("3.2", cal2.version)
28
+ assert_equal("test-prodid", cal2.prodid)
29
+ end
30
+
31
+ def test_block_creation
32
+ cal = Icalendar::Calendar.new
33
+ cal.event do
34
+ dtend "19970903T190000Z"
35
+ summary "This is my summary"
36
+ end
37
+
38
+ event = cal.event
39
+ event.dtend = "19970903T190000Z"
40
+ event.summary = "This is my summary"
41
+
42
+ ev = cal.events.each do |ev|
43
+ assert_equal("19970903T190000Z", ev.dtend)
44
+ end
45
+ end
46
46
  end
@@ -32,7 +32,7 @@ class TestVevent < Test::Unit::TestCase
32
32
  def test_single_properties
33
33
  @event.klass = "PRIVATE"
34
34
 
35
- @cal.add(@event)
35
+ @cal.add_component(@event)
36
36
 
37
37
  cals = Icalendar::Parser.new(@cal.to_ical).parse
38
38
  cal2 = cals.first
@@ -6,69 +6,69 @@ require 'icalendar'
6
6
 
7
7
  class TestComponent < Test::Unit::TestCase
8
8
 
9
- # Create a calendar with an event for each test.
10
- def setup
11
- @cal = Icalendar::Calendar.new
12
- @event = Icalendar::Event.new
13
- end
9
+ # Create a calendar with an event for each test.
10
+ def setup
11
+ @cal = Icalendar::Calendar.new
12
+ @event = Icalendar::Event.new
13
+ end
14
14
 
15
- def test_ical_property
16
- # No alias but it does have a prop_name
17
- assert_equal(@event.klass?, false)
18
- @event.klass = "PRIVATE"
19
- assert_equal(@event.klass?, true)
20
- assert_equal(@event.klass, "PRIVATE")
21
-
22
- # Check that both dtstart and its alias start work correctly
23
- date = DateTime.new(2005, 02, 05, 23, 24, 25)
24
- @event.dtend = date
25
- assert_equal(@event.dtend.year, date.year)
15
+ def test_ical_property
16
+ # No alias but it does have a prop_name
17
+ assert_equal(@event.klass?, false)
18
+ @event.klass = "PRIVATE"
19
+ assert_equal(@event.klass?, true)
20
+ assert_equal(@event.klass, "PRIVATE")
26
21
 
27
- date2 = DateTime.new(2005, 02, 05, 23, 24, 26)
28
- @event.end = date2
29
- assert_equal(@event.end.year, date2.year)
30
- end
22
+ # Check that both dtstart and its alias start work correctly
23
+ date = DateTime.new(2005, 02, 05, 23, 24, 25)
24
+ @event.dtend = date
25
+ assert_equal(@event.dtend.year, date.year)
31
26
 
32
- def test_ical_multi_property
33
- # Query
34
- assert_equal(@event.comments?, false)
35
- @event.comments = []
36
- assert_equal(@event.comments?, true)
37
-
38
- # Should return an empty array, rather than nil
39
- assert_equal(@event.comments.size, 0)
27
+ date2 = DateTime.new(2005, 02, 05, 23, 24, 26)
28
+ @event.end = date2
29
+ assert_equal(@event.end.year, date2.year)
30
+ end
40
31
 
41
- # Add and remove
42
- @event.add_comment "c1"
43
- @event.add_comment "c2"
44
- assert_equal(@event.comments.size, 2)
45
- assert_equal(@event.comments, ["c1", "c2"])
46
- @event.remove_comment "c1"
47
- assert_equal(@event.comments, ["c2"])
32
+ def test_ical_multi_property
33
+ # Query
34
+ assert_equal(@event.comments?, false)
35
+ @event.comments = []
36
+ assert_equal(@event.comments?, true)
48
37
 
49
- # Set & get whole array
50
- foo = ["as", "df"]
51
- @event.comments = foo
52
- assert_equal(@event.comments, foo)
38
+ # Should return an empty array, rather than nil
39
+ assert_equal(@event.comments.size, 0)
53
40
 
54
- foo = ["asdf", "qwer"]
55
- @event.comments(foo)
56
- assert_equal(@event.comments, foo)
41
+ # Add and remove
42
+ @event.add_comment "c1"
43
+ @event.add_comment "c2"
44
+ assert_equal(@event.comments.size, 2)
45
+ assert_equal(@event.comments, ["c1", "c2"])
46
+ @event.remove_comment "c1"
47
+ assert_equal(@event.comments, ["c2"])
57
48
 
58
- # Error cases
59
- assert_raise(ArgumentError) { @event.comments("asdf") }
60
- end
49
+ # Set & get whole array
50
+ foo = ["as", "df"]
51
+ @event.comments = foo
52
+ assert_equal(@event.comments, foo)
61
53
 
62
- def test_bad_args
63
- # Single property
64
- assert_raise(NotImplementedError) do
65
- @event.klass = {}
66
- end
67
-
68
- # Multi property
69
- assert_raise(NotImplementedError) do
70
- @event.comments = [{}]
71
- end
72
- end
54
+ foo = ["asdf", "qwer"]
55
+ @event.comments(foo)
56
+ assert_equal(@event.comments, foo)
57
+
58
+ # Error cases
59
+ assert_raise(ArgumentError) { @event.comments("asdf") }
60
+ end
61
+
62
+ def test_bad_args
63
+ # Single property
64
+ assert_raise(NotImplementedError) do
65
+ @event.klass = {}
66
+ end
67
+
68
+ # Multi property
69
+ assert_raise(NotImplementedError) do
70
+ @event.comments = [{}]
71
+ end
72
+ end
73
73
 
74
74
  end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # NOTE: you must have installed ruby-breakpoint in order to use this script.
4
+ # Grab it using gem with "gem install ruby-breakpoint --remote" or download
5
+ # from the website (http://ruby-breakpoint.rubyforge.org/) then run setup.rb
6
+
7
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
8
+
9
+ require 'breakpoint'
10
+
11
+ require 'icalendar'
12
+
13
+ cal = Icalendar::Parser.new(File.new("life.ics")).parse
14
+
15
+ breakpoint
data/test/life.ics ADDED
@@ -0,0 +1,45 @@
1
+ BEGIN:VCALENDAR
2
+ VERSION:2.0
3
+ X-WR-CALNAME:Life
4
+ PRODID:-//Apple Computer\, Inc//iCal 2.0//EN
5
+ X-WR-RELCALID:69FB0467-7E07-4DE7-901D-B70242B3DB25
6
+ X-WR-TIMEZONE:America/Chicago
7
+ CALSCALE:GREGORIAN
8
+ METHOD:PUBLISH
9
+ BEGIN:VTIMEZONE
10
+ TZID:America/Chicago
11
+ LAST-MODIFIED:20050825T194346Z
12
+ BEGIN:DAYLIGHT
13
+ DTSTART:20050403T080000
14
+ TZOFFSETTO:-0500
15
+ TZOFFSETFROM:+0000
16
+ TZNAME:CDT
17
+ END:DAYLIGHT
18
+ BEGIN:STANDARD
19
+ DTSTART:20051030T020000
20
+ TZOFFSETTO:-0600
21
+ TZOFFSETFROM:-0500
22
+ TZNAME:CST
23
+ END:STANDARD
24
+ END:VTIMEZONE
25
+ BEGIN:VEVENT
26
+ UID:bsuidfortestabc123
27
+ ORGANIZER:mailto:joebob@random.net
28
+ ATTACH:http://bush.sucks.org/impeach/him.rhtml
29
+ ATTACH:http://corporations-dominate.existence.net/why.rhtml
30
+ SUMMARY:This is a really long summary
31
+ to test the method of unfolding lines
32
+ so I'm just going to ma
33
+ ke it
34
+ a whol
35
+ e
36
+ bunch of lines.
37
+ CLASS:PRIVATE
38
+ PRIORITY:2
39
+ GEO:37.386013;-122.0829322
40
+ DTSTART;TZID=US-Mountain:20050120T170000
41
+ DTEND:20050120T184500
42
+ DTSTAMP:20050118T211523Z
43
+ END:VEVENT
44
+ END:VCALENDAR
45
+
@@ -0,0 +1,20 @@
1
+ # Test out property parameter functionality
2
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
3
+
4
+ require 'date'
5
+ require 'test/unit'
6
+ require 'icalendar'
7
+
8
+ class TestComponent < Test::Unit::TestCase
9
+
10
+ # Create a calendar with an event for each test.
11
+ def setup
12
+ @cal = Icalendar::Calendar.new
13
+ @event = Icalendar::Event.new
14
+ end
15
+
16
+ def test_property_parameters
17
+ @event.summary = "This is a test summary.",
18
+ {"ALTREP" => "http://my.language.net", "LANGUAGE" => "SPANISH"}
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.1
2
+ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: icalendar
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.95"
7
- date: 2005-06-12
6
+ version: "0.96"
7
+ date: 2005-10-10 00:00:00 +02:00
8
8
  summary: A ruby implementation of the iCalendar specification (RFC-2445).
9
9
  require_paths:
10
10
  - lib
11
- author: Jeff Rose
12
11
  email: rosejn@gmail.com
13
12
  homepage: http://icalendar.rubyforge.org/
14
13
  rubyforge_project:
@@ -27,95 +26,49 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
27
26
  version: 0.0.0
28
27
  version:
29
28
  platform: ruby
29
+ signing_key:
30
+ cert_chain:
31
+ authors:
32
+ - Jeff Rose
30
33
  files:
31
- - test/calendar_test.rb
32
- - test/single_event.ics
33
- - test/simplecal.ics
34
34
  - test/component
35
+ - test/component_test.rb
36
+ - test/single_event.ics
35
37
  - test/property_helpers.rb
38
+ - test/simplecal.ics
39
+ - test/life.ics
40
+ - test/calendar_test.rb
36
41
  - test/parser_test.rb
37
- - test/component_test.rb
42
+ - test/parameter_test.rb
43
+ - test/interactive.rb
38
44
  - test/component/event_test.rb
39
45
  - lib/icalendar
40
46
  - lib/icalendar.rb
41
- - lib/icalendar/parser.rb
42
- - lib/icalendar/calendar.rb
43
- - lib/icalendar/parameter.rb
44
- - lib/icalendar/helpers.rb
45
47
  - lib/icalendar/component
46
- - "lib/icalendar/#helpers.rb#"
48
+ - lib/icalendar/conversions.rb
49
+ - lib/icalendar/parameter.rb
47
50
  - lib/icalendar/component.rb
51
+ - lib/icalendar/helpers.rb
52
+ - lib/icalendar/calendar.rb
48
53
  - lib/icalendar/base.rb
49
- - lib/icalendar/conversions.rb
54
+ - lib/icalendar/parser.rb
55
+ - lib/icalendar/foo.rb
50
56
  - lib/icalendar/component/freebusy.rb
57
+ - lib/icalendar/component/event.rb
51
58
  - lib/icalendar/component/journal.rb
52
59
  - lib/icalendar/component/todo.rb
53
- - lib/icalendar/component/event.rb
54
- - lib/icalendar/component/alarm.rb
55
60
  - lib/icalendar/component/timezone.rb
56
- - docs/api
61
+ - lib/icalendar/component/alarm.rb
57
62
  - docs/rfcs
58
63
  - docs/examples
59
- - docs/api/files
60
- - docs/api/index.html
61
- - docs/api/rdoc-style.css
62
- - docs/api/fr_method_index.html
63
- - docs/api/fr_class_index.html
64
- - docs/api/fr_file_index.html
65
- - docs/api/created.rid
66
- - docs/api/classes
67
- - docs/api/files/lib
68
- - docs/api/files/GPL.html
69
- - docs/api/files/README.html
70
- - docs/api/files/COPYING.html
71
- - docs/api/files/lib/icalendar
72
- - docs/api/files/lib/icalendar_rb.html
73
- - docs/api/files/lib/icalendar/component
74
- - docs/api/files/lib/icalendar/parser_rb.html
75
- - docs/api/files/lib/icalendar/component_rb.html
76
- - docs/api/files/lib/icalendar/parameter_rb.html
77
- - docs/api/files/lib/icalendar/calendar_rb.html
78
- - docs/api/files/lib/icalendar/helpers_rb.html
79
- - docs/api/files/lib/icalendar/base_rb.html
80
- - docs/api/files/lib/icalendar/conversions_rb.html
81
- - docs/api/files/lib/icalendar/component/journal_rb.html
82
- - docs/api/files/lib/icalendar/component/event_rb.html
83
- - docs/api/files/lib/icalendar/component/todo_rb.html
84
- - docs/api/files/lib/icalendar/component/timezone_rb.html
85
- - docs/api/files/lib/icalendar/component/alarm_rb.html
86
- - docs/api/files/lib/icalendar/component/freebusy_rb.html
87
- - docs/api/classes/String.html
88
- - docs/api/classes/DateTime.html
89
- - docs/api/classes/Icalendar
90
- - docs/api/classes/Float.html
91
- - docs/api/classes/Fixnum.html
92
- - docs/api/classes/Array.html
93
- - docs/api/classes/Time.html
94
- - docs/api/classes/Date.html
95
- - docs/api/classes/Icalendar/Parser.html
96
- - docs/api/classes/Icalendar/InvalidPropertyValue.html
97
- - docs/api/classes/Icalendar/Alarm.html
98
- - docs/api/classes/Icalendar/Todo.html
99
- - docs/api/classes/Icalendar/Journal.html
100
- - docs/api/classes/Icalendar/Component.html
101
- - docs/api/classes/Icalendar/Parameter.html
102
- - docs/api/classes/Icalendar/Timezone.html
103
- - docs/api/classes/Icalendar/Calendar.html
104
- - docs/api/classes/Icalendar/Base.html
105
- - docs/api/classes/Icalendar/Freebusy.html
106
- - docs/api/classes/Icalendar/Event.html
107
- - docs/api/classes/Icalendar/DateProp.html
108
- - docs/api/classes/Icalendar/DateProp
109
- - docs/api/classes/Icalendar/InvalidComponentClass.html
110
- - docs/api/classes/Icalendar/DateProp/ClassMethods.html
111
64
  - docs/rfcs/rfc2425.pdf
112
65
  - docs/rfcs/rfc2426.pdf
113
66
  - docs/rfcs/rfc2445.pdf
114
67
  - docs/rfcs/rfc2446.pdf
115
68
  - docs/rfcs/rfc2447.pdf
116
69
  - docs/rfcs/rfc3283.txt
117
- - docs/examples/create_cal.rb
118
70
  - docs/examples/single_event.ics
71
+ - docs/examples/create_cal.rb
119
72
  - docs/examples/parse_cal.rb
120
73
  - Rakefile
121
74
  - README