icalendar 0.96.4 → 0.97

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. data/README +66 -53
  2. data/Rakefile +33 -24
  3. data/docs/api/classes/Array.html +9 -11
  4. data/docs/api/classes/Array.src/M000002.html +18 -0
  5. data/docs/api/classes/Date.html +2 -22
  6. data/docs/api/classes/Date.src/M000004.html +29 -0
  7. data/docs/api/classes/DateTime.html +2 -43
  8. data/docs/api/classes/DateTime.src/M000005.html +50 -0
  9. data/docs/api/classes/Fixnum.html +2 -11
  10. data/docs/api/classes/Fixnum.src/M000011.html +18 -0
  11. data/docs/api/classes/Float.html +2 -11
  12. data/docs/api/classes/Float.src/M000003.html +18 -0
  13. data/docs/api/classes/HashAttrs.html +15 -60
  14. data/docs/api/classes/HashAttrs.src/M000068.html +26 -0
  15. data/docs/api/classes/HashAttrs.src/M000069.html +27 -0
  16. data/docs/api/classes/HashAttrs.src/M000070.html +19 -0
  17. data/docs/api/classes/Icalendar/Alarm.html +5 -15
  18. data/docs/api/classes/Icalendar/Alarm.src/M000020.html +22 -0
  19. data/docs/api/classes/Icalendar/Base.html +41 -0
  20. data/docs/api/classes/Icalendar/Base.src/M000022.html +18 -0
  21. data/docs/api/classes/Icalendar/Base.src/M000023.html +18 -0
  22. data/docs/api/classes/Icalendar/Calendar.html +116 -116
  23. data/docs/api/classes/Icalendar/Calendar.src/M000054.html +23 -0
  24. data/docs/api/classes/Icalendar/Calendar.src/M000055.html +23 -0
  25. data/docs/api/classes/Icalendar/Calendar.src/M000056.html +18 -0
  26. data/docs/api/classes/Icalendar/Calendar.src/M000057.html +23 -0
  27. data/docs/api/classes/Icalendar/Calendar.src/M000058.html +18 -0
  28. data/docs/api/classes/Icalendar/Calendar.src/M000059.html +23 -0
  29. data/docs/api/classes/Icalendar/Calendar.src/M000060.html +18 -0
  30. data/docs/api/classes/Icalendar/Calendar.src/M000061.html +23 -0
  31. data/docs/api/classes/Icalendar/Calendar.src/M000062.html +18 -0
  32. data/docs/api/classes/Icalendar/Calendar.src/M000063.html +23 -0
  33. data/docs/api/classes/Icalendar/Calendar.src/M000064.html +19 -0
  34. data/docs/api/classes/Icalendar/Component.html +200 -367
  35. data/docs/api/classes/Icalendar/Component.src/M000029.html +22 -0
  36. data/docs/api/classes/Icalendar/Component.src/M000030.html +24 -0
  37. data/docs/api/classes/Icalendar/Component.src/M000035.html +22 -0
  38. data/docs/api/classes/Icalendar/Component.src/M000040.html +18 -0
  39. data/docs/api/classes/Icalendar/Component.src/M000041.html +24 -0
  40. data/docs/api/classes/Icalendar/Component.src/M000042.html +28 -0
  41. data/docs/api/classes/Icalendar/Component.src/M000043.html +37 -0
  42. data/docs/api/classes/Icalendar/Component.src/M000044.html +37 -0
  43. data/docs/api/classes/Icalendar/Component.src/M000045.html +18 -0
  44. data/docs/api/classes/Icalendar/Component.src/M000046.html +18 -0
  45. data/docs/api/classes/Icalendar/Component.src/M000047.html +18 -0
  46. data/docs/api/classes/Icalendar/Component.src/M000048.html +26 -0
  47. data/docs/api/classes/Icalendar/Component.src/M000049.html +29 -0
  48. data/docs/api/classes/Icalendar/Component.src/M000050.html +22 -0
  49. data/docs/api/classes/Icalendar/DateProp.html +2 -12
  50. data/docs/api/classes/Icalendar/DateProp.src/M000013.html +19 -0
  51. data/docs/api/classes/Icalendar/DateProp/ClassMethods.html +2 -59
  52. data/docs/api/classes/Icalendar/DateProp/ClassMethods.src/M000014.html +66 -0
  53. data/docs/api/classes/Icalendar/Daylight.html +5 -14
  54. data/docs/api/classes/Icalendar/Daylight.src/M000051.html +18 -0
  55. data/docs/api/classes/Icalendar/Event.html +30 -37
  56. data/docs/api/classes/Icalendar/Event.src/M000052.html +23 -0
  57. data/docs/api/classes/Icalendar/Event.src/M000053.html +23 -0
  58. data/docs/api/classes/Icalendar/Freebusy.html +5 -14
  59. data/docs/api/classes/Icalendar/Freebusy.src/M000065.html +21 -0
  60. data/docs/api/classes/Icalendar/Geo.html +192 -0
  61. data/docs/api/classes/Icalendar/Geo.src/M000024.html +19 -0
  62. data/docs/api/classes/Icalendar/Geo.src/M000025.html +18 -0
  63. data/docs/api/classes/Icalendar/Journal.html +2 -11
  64. data/docs/api/classes/Icalendar/Journal.src/M000016.html +22 -0
  65. data/docs/api/classes/Icalendar/Parameter.html +5 -23
  66. data/docs/api/classes/Icalendar/Parameter.src/M000066.html +27 -0
  67. data/docs/api/classes/Icalendar/Parser.html +36 -212
  68. data/docs/api/classes/Icalendar/Parser.src/M000017.html +32 -0
  69. data/docs/api/classes/Icalendar/Parser.src/M000018.html +43 -0
  70. data/docs/api/classes/Icalendar/Parser.src/M000019.html +33 -0
  71. data/docs/api/classes/Icalendar/Standard.html +2 -11
  72. data/docs/api/classes/Icalendar/Standard.src/M000015.html +18 -0
  73. data/docs/api/classes/Icalendar/Timezone.html +16 -48
  74. data/docs/api/classes/Icalendar/Timezone.src/M000026.html +19 -0
  75. data/docs/api/classes/Icalendar/Timezone.src/M000027.html +22 -0
  76. data/docs/api/classes/Icalendar/Timezone.src/M000028.html +18 -0
  77. data/docs/api/classes/Icalendar/Todo.html +5 -14
  78. data/docs/api/classes/Icalendar/Todo.src/M000021.html +22 -0
  79. data/docs/api/classes/Object.html +10 -59
  80. data/docs/api/classes/Object.src/M000006.html +20 -0
  81. data/docs/api/classes/Object.src/M000007.html +18 -0
  82. data/docs/api/classes/Object.src/M000008.html +20 -0
  83. data/docs/api/classes/Object.src/M000009.html +18 -0
  84. data/docs/api/classes/Object.src/M000010.html +18 -0
  85. data/docs/api/classes/String.html +2 -11
  86. data/docs/api/classes/String.src/M000012.html +18 -0
  87. data/docs/api/classes/Time.html +2 -26
  88. data/docs/api/classes/Time.src/M000001.html +37 -0
  89. data/docs/api/classes/URI/Generic.html +5 -14
  90. data/docs/api/classes/URI/Generic.src/M000067.html +18 -0
  91. data/docs/api/created.rid +1 -1
  92. data/docs/api/files/COPYING.html +1 -1
  93. data/docs/api/files/GPL.html +1 -1
  94. data/docs/api/files/README.html +76 -64
  95. data/docs/api/files/lib/hash_attrs_rb.html +1 -1
  96. data/docs/api/files/lib/icalendar/base_rb.html +1 -1
  97. data/docs/api/files/lib/icalendar/calendar_rb.html +1 -1
  98. data/docs/api/files/lib/icalendar/component/alarm_rb.html +1 -1
  99. data/docs/api/files/lib/icalendar/component/event_rb.html +1 -1
  100. data/docs/api/files/lib/icalendar/component/freebusy_rb.html +1 -1
  101. data/docs/api/files/lib/icalendar/component/journal_rb.html +1 -1
  102. data/docs/api/files/lib/icalendar/component/timezone_rb.html +1 -1
  103. data/docs/api/files/lib/icalendar/component/todo_rb.html +1 -1
  104. data/docs/api/files/lib/icalendar/component_rb.html +8 -1
  105. data/docs/api/files/lib/icalendar/conversions_rb.html +1 -1
  106. data/docs/api/files/lib/icalendar/helpers_rb.html +1 -1
  107. data/docs/api/files/lib/icalendar/parameter_rb.html +1 -1
  108. data/docs/api/files/lib/icalendar/parser_rb.html +2 -1
  109. data/docs/api/files/lib/icalendar_rb.html +1 -1
  110. data/docs/api/files/lib/meta_rb.html +1 -1
  111. data/docs/api/fr_class_index.html +1 -0
  112. data/docs/api/fr_method_index.html +57 -41
  113. data/docs/rfcs/itip_notes.txt +69 -0
  114. data/examples/create_cal.rb +33 -32
  115. data/examples/parse_cal.rb +2 -2
  116. data/lib/icalendar/base.rb +8 -0
  117. data/lib/icalendar/calendar.rb +32 -3
  118. data/lib/icalendar/component.rb +187 -113
  119. data/lib/icalendar/component/alarm.rb +3 -0
  120. data/lib/icalendar/component/event.rb +9 -3
  121. data/lib/icalendar/component/freebusy.rb +3 -0
  122. data/lib/icalendar/component/journal.rb +4 -0
  123. data/lib/icalendar/component/todo.rb +4 -0
  124. data/lib/icalendar/conversions.rb +7 -1
  125. data/lib/icalendar/parser.rb +68 -90
  126. data/test/calendar_test.rb +32 -8
  127. data/test/component/event_test.rb +4 -7
  128. data/test/component/todo_test.rb +13 -0
  129. data/test/component_test.rb +21 -34
  130. data/test/conversions_test.rb +66 -0
  131. data/test/coverage/-home-rosejn-projects-icalendar-lib-hash_attrs_rb.html +574 -0
  132. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-base_rb.html +575 -0
  133. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-calendar_rb.html +629 -0
  134. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-alarm_rb.html +581 -0
  135. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-event_rb.html +658 -0
  136. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-freebusy_rb.html +574 -0
  137. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-journal_rb.html +597 -0
  138. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-timezone_rb.html +625 -0
  139. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-todo_rb.html +600 -0
  140. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component_rb.html +924 -0
  141. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-conversions_rb.html +667 -0
  142. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-parser_rb.html +938 -0
  143. data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar_rb.html +576 -0
  144. data/test/coverage/-home-rosejn-projects-icalendar-lib-meta_rb.html +572 -0
  145. data/test/coverage/calendar_test_rb.html +590 -0
  146. data/test/coverage/component_test_rb.html +602 -0
  147. data/test/coverage/index.html +1009 -0
  148. data/test/coverage/lib-hash_attrs_rb.html +574 -0
  149. data/test/coverage/lib-icalendar-base_rb.html +583 -0
  150. data/test/coverage/lib-icalendar-calendar_rb.html +631 -0
  151. data/test/coverage/lib-icalendar-component-alarm_rb.html +581 -0
  152. data/test/coverage/lib-icalendar-component-event_rb.html +661 -0
  153. data/test/coverage/lib-icalendar-component-freebusy_rb.html +576 -0
  154. data/test/coverage/lib-icalendar-component-journal_rb.html +599 -0
  155. data/test/coverage/lib-icalendar-component-timezone_rb.html +625 -0
  156. data/test/coverage/lib-icalendar-component-todo_rb.html +602 -0
  157. data/test/coverage/lib-icalendar-component_rb.html +941 -0
  158. data/test/coverage/lib-icalendar-conversions_rb.html +673 -0
  159. data/test/coverage/lib-icalendar-parser_rb.html +916 -0
  160. data/test/coverage/lib-icalendar_rb.html +576 -0
  161. data/test/coverage/lib-meta_rb.html +572 -0
  162. data/test/coverage/parameter_test_rb.html +569 -0
  163. data/test/coverage/parser_test_rb.html +623 -0
  164. data/test/coverage/test-calendar_test_rb.html +590 -0
  165. data/test/coverage/test-component-event_test_rb.html +584 -0
  166. data/test/coverage/test-component_test_rb.html +606 -0
  167. data/test/coverage/test-conversions_test_rb.html +603 -0
  168. data/test/coverage/test-parameter_test_rb.html +569 -0
  169. data/test/coverage/test-parser_test_rb.html +624 -0
  170. data/test/interactive.rb +3 -1
  171. data/test/life.ics +46 -1092
  172. data/test/parameter_test.rb +11 -2
  173. data/test/parser_test.rb +12 -11
  174. metadata +259 -126
  175. data/test/old_life.ics +0 -46
  176. data/test/rw.ics +0 -947
@@ -0,0 +1,938 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'><head><title>/home/rosejn/projects/icalendar/lib/icalendar/parser.rb - C0 code coverage information</title><style type='text/css'>body { background-color: rgb(240, 240, 245); }</style><style type='text/css'>span.marked {
2
+ background-color: rgb(185, 200, 200);
3
+ display: block;
4
+ }
5
+ span.inferred {
6
+ background-color: rgb(170, 185, 185);
7
+ display: block;
8
+ }
9
+ span.overview {
10
+ border-bottom: 8px solid black;
11
+ }
12
+ div.overview {
13
+ border-bottom: 8px solid black;
14
+ }
15
+ body {
16
+ font-family: verdana, arial, helvetica;
17
+ }
18
+ div.footer {
19
+ font-size: 68%;
20
+ margin-top: 1.5em;
21
+ }
22
+ h1, h2, h3, h4, h5, h6 {
23
+ margin-bottom: 0.5em;
24
+ }
25
+ h5 {
26
+ margin-top: 0.5em;
27
+ }
28
+ .hidden {
29
+ display: none;
30
+ }
31
+ div.separator {
32
+ height: 10px;
33
+ }
34
+ table tr td, table tr th {
35
+ font-size: 68%;
36
+ }
37
+ td.value table tr td {
38
+ font-size: 11px;
39
+ }
40
+ table.percent_graph {
41
+ height: 12px;
42
+ border: #808080 1px solid;
43
+ empty-cells: show;
44
+ }
45
+ table.percent_graph td.covered {
46
+ height: 10px;
47
+ background: #00f000;
48
+ }
49
+ table.percent_graph td.uncovered {
50
+ height: 10px;
51
+ background: #e00000;
52
+ }
53
+ table.percent_graph td.NA {
54
+ height: 10px;
55
+ background: #eaeaea;
56
+ }
57
+ table.report {
58
+ border-collapse: collapse;
59
+ width: 100%;
60
+ }
61
+ table.report td.heading {
62
+ background: #dcecff;
63
+ border: #d0d0d0 1px solid;
64
+ font-weight: bold;
65
+ text-align: center;
66
+ }
67
+ table.report td.heading:hover {
68
+ background: #c0ffc0;
69
+ }
70
+ table.report td.text {
71
+ border: #d0d0d0 1px solid;
72
+ }
73
+ table.report td.value {
74
+ text-align: right;
75
+ border: #d0d0d0 1px solid;
76
+ }
77
+ </style><style type='text/css'>span.run0 {
78
+ background-color: rgb(178, 204, 255);
79
+ display: block;
80
+ }
81
+ span.run1 {
82
+ background-color: rgb(178, 206, 255);
83
+ display: block;
84
+ }
85
+ span.run2 {
86
+ background-color: rgb(178, 209, 255);
87
+ display: block;
88
+ }
89
+ span.run3 {
90
+ background-color: rgb(178, 211, 255);
91
+ display: block;
92
+ }
93
+ span.run4 {
94
+ background-color: rgb(178, 214, 255);
95
+ display: block;
96
+ }
97
+ span.run5 {
98
+ background-color: rgb(178, 218, 255);
99
+ display: block;
100
+ }
101
+ span.run6 {
102
+ background-color: rgb(178, 220, 255);
103
+ display: block;
104
+ }
105
+ span.run7 {
106
+ background-color: rgb(178, 223, 255);
107
+ display: block;
108
+ }
109
+ span.run8 {
110
+ background-color: rgb(178, 225, 255);
111
+ display: block;
112
+ }
113
+ span.run9 {
114
+ background-color: rgb(178, 228, 255);
115
+ display: block;
116
+ }
117
+ span.run10 {
118
+ background-color: rgb(178, 232, 255);
119
+ display: block;
120
+ }
121
+ span.run11 {
122
+ background-color: rgb(178, 234, 255);
123
+ display: block;
124
+ }
125
+ span.run12 {
126
+ background-color: rgb(178, 237, 255);
127
+ display: block;
128
+ }
129
+ span.run13 {
130
+ background-color: rgb(178, 239, 255);
131
+ display: block;
132
+ }
133
+ span.run14 {
134
+ background-color: rgb(178, 242, 255);
135
+ display: block;
136
+ }
137
+ span.run15 {
138
+ background-color: rgb(178, 246, 255);
139
+ display: block;
140
+ }
141
+ span.run16 {
142
+ background-color: rgb(178, 248, 255);
143
+ display: block;
144
+ }
145
+ span.run17 {
146
+ background-color: rgb(178, 251, 255);
147
+ display: block;
148
+ }
149
+ span.run18 {
150
+ background-color: rgb(178, 253, 255);
151
+ display: block;
152
+ }
153
+ span.run19 {
154
+ background-color: rgb(178, 255, 253);
155
+ display: block;
156
+ }
157
+ span.run20 {
158
+ background-color: rgb(178, 255, 249);
159
+ display: block;
160
+ }
161
+ span.run21 {
162
+ background-color: rgb(178, 255, 247);
163
+ display: block;
164
+ }
165
+ span.run22 {
166
+ background-color: rgb(178, 255, 244);
167
+ display: block;
168
+ }
169
+ span.run23 {
170
+ background-color: rgb(178, 255, 242);
171
+ display: block;
172
+ }
173
+ span.run24 {
174
+ background-color: rgb(178, 255, 239);
175
+ display: block;
176
+ }
177
+ span.run25 {
178
+ background-color: rgb(178, 255, 235);
179
+ display: block;
180
+ }
181
+ span.run26 {
182
+ background-color: rgb(178, 255, 233);
183
+ display: block;
184
+ }
185
+ span.run27 {
186
+ background-color: rgb(178, 255, 230);
187
+ display: block;
188
+ }
189
+ span.run28 {
190
+ background-color: rgb(178, 255, 228);
191
+ display: block;
192
+ }
193
+ span.run29 {
194
+ background-color: rgb(178, 255, 225);
195
+ display: block;
196
+ }
197
+ span.run30 {
198
+ background-color: rgb(178, 255, 221);
199
+ display: block;
200
+ }
201
+ span.run31 {
202
+ background-color: rgb(178, 255, 219);
203
+ display: block;
204
+ }
205
+ span.run32 {
206
+ background-color: rgb(178, 255, 216);
207
+ display: block;
208
+ }
209
+ span.run33 {
210
+ background-color: rgb(178, 255, 214);
211
+ display: block;
212
+ }
213
+ span.run34 {
214
+ background-color: rgb(178, 255, 211);
215
+ display: block;
216
+ }
217
+ span.run35 {
218
+ background-color: rgb(178, 255, 207);
219
+ display: block;
220
+ }
221
+ span.run36 {
222
+ background-color: rgb(178, 255, 205);
223
+ display: block;
224
+ }
225
+ span.run37 {
226
+ background-color: rgb(178, 255, 202);
227
+ display: block;
228
+ }
229
+ span.run38 {
230
+ background-color: rgb(178, 255, 200);
231
+ display: block;
232
+ }
233
+ span.run39 {
234
+ background-color: rgb(178, 255, 197);
235
+ display: block;
236
+ }
237
+ span.run40 {
238
+ background-color: rgb(178, 255, 193);
239
+ display: block;
240
+ }
241
+ span.run41 {
242
+ background-color: rgb(178, 255, 191);
243
+ display: block;
244
+ }
245
+ span.run42 {
246
+ background-color: rgb(178, 255, 188);
247
+ display: block;
248
+ }
249
+ span.run43 {
250
+ background-color: rgb(178, 255, 186);
251
+ display: block;
252
+ }
253
+ span.run44 {
254
+ background-color: rgb(178, 255, 183);
255
+ display: block;
256
+ }
257
+ span.run45 {
258
+ background-color: rgb(178, 255, 179);
259
+ display: block;
260
+ }
261
+ span.run46 {
262
+ background-color: rgb(179, 255, 178);
263
+ display: block;
264
+ }
265
+ span.run47 {
266
+ background-color: rgb(182, 255, 178);
267
+ display: block;
268
+ }
269
+ span.run48 {
270
+ background-color: rgb(184, 255, 178);
271
+ display: block;
272
+ }
273
+ span.run49 {
274
+ background-color: rgb(187, 255, 178);
275
+ display: block;
276
+ }
277
+ span.run50 {
278
+ background-color: rgb(191, 255, 178);
279
+ display: block;
280
+ }
281
+ span.run51 {
282
+ background-color: rgb(193, 255, 178);
283
+ display: block;
284
+ }
285
+ span.run52 {
286
+ background-color: rgb(196, 255, 178);
287
+ display: block;
288
+ }
289
+ span.run53 {
290
+ background-color: rgb(198, 255, 178);
291
+ display: block;
292
+ }
293
+ span.run54 {
294
+ background-color: rgb(201, 255, 178);
295
+ display: block;
296
+ }
297
+ span.run55 {
298
+ background-color: rgb(205, 255, 178);
299
+ display: block;
300
+ }
301
+ span.run56 {
302
+ background-color: rgb(207, 255, 178);
303
+ display: block;
304
+ }
305
+ span.run57 {
306
+ background-color: rgb(210, 255, 178);
307
+ display: block;
308
+ }
309
+ span.run58 {
310
+ background-color: rgb(212, 255, 178);
311
+ display: block;
312
+ }
313
+ span.run59 {
314
+ background-color: rgb(215, 255, 178);
315
+ display: block;
316
+ }
317
+ span.run60 {
318
+ background-color: rgb(219, 255, 178);
319
+ display: block;
320
+ }
321
+ span.run61 {
322
+ background-color: rgb(221, 255, 178);
323
+ display: block;
324
+ }
325
+ span.run62 {
326
+ background-color: rgb(224, 255, 178);
327
+ display: block;
328
+ }
329
+ span.run63 {
330
+ background-color: rgb(226, 255, 178);
331
+ display: block;
332
+ }
333
+ span.run64 {
334
+ background-color: rgb(229, 255, 178);
335
+ display: block;
336
+ }
337
+ span.run65 {
338
+ background-color: rgb(233, 255, 178);
339
+ display: block;
340
+ }
341
+ span.run66 {
342
+ background-color: rgb(235, 255, 178);
343
+ display: block;
344
+ }
345
+ span.run67 {
346
+ background-color: rgb(238, 255, 178);
347
+ display: block;
348
+ }
349
+ span.run68 {
350
+ background-color: rgb(240, 255, 178);
351
+ display: block;
352
+ }
353
+ span.run69 {
354
+ background-color: rgb(243, 255, 178);
355
+ display: block;
356
+ }
357
+ span.run70 {
358
+ background-color: rgb(247, 255, 178);
359
+ display: block;
360
+ }
361
+ span.run71 {
362
+ background-color: rgb(249, 255, 178);
363
+ display: block;
364
+ }
365
+ span.run72 {
366
+ background-color: rgb(252, 255, 178);
367
+ display: block;
368
+ }
369
+ span.run73 {
370
+ background-color: rgb(255, 255, 178);
371
+ display: block;
372
+ }
373
+ span.run74 {
374
+ background-color: rgb(255, 252, 178);
375
+ display: block;
376
+ }
377
+ span.run75 {
378
+ background-color: rgb(255, 248, 178);
379
+ display: block;
380
+ }
381
+ span.run76 {
382
+ background-color: rgb(255, 246, 178);
383
+ display: block;
384
+ }
385
+ span.run77 {
386
+ background-color: rgb(255, 243, 178);
387
+ display: block;
388
+ }
389
+ span.run78 {
390
+ background-color: rgb(255, 240, 178);
391
+ display: block;
392
+ }
393
+ span.run79 {
394
+ background-color: rgb(255, 238, 178);
395
+ display: block;
396
+ }
397
+ span.run80 {
398
+ background-color: rgb(255, 234, 178);
399
+ display: block;
400
+ }
401
+ span.run81 {
402
+ background-color: rgb(255, 232, 178);
403
+ display: block;
404
+ }
405
+ span.run82 {
406
+ background-color: rgb(255, 229, 178);
407
+ display: block;
408
+ }
409
+ span.run83 {
410
+ background-color: rgb(255, 226, 178);
411
+ display: block;
412
+ }
413
+ span.run84 {
414
+ background-color: rgb(255, 224, 178);
415
+ display: block;
416
+ }
417
+ span.run85 {
418
+ background-color: rgb(255, 220, 178);
419
+ display: block;
420
+ }
421
+ span.run86 {
422
+ background-color: rgb(255, 218, 178);
423
+ display: block;
424
+ }
425
+ span.run87 {
426
+ background-color: rgb(255, 215, 178);
427
+ display: block;
428
+ }
429
+ span.run88 {
430
+ background-color: rgb(255, 212, 178);
431
+ display: block;
432
+ }
433
+ span.run89 {
434
+ background-color: rgb(255, 210, 178);
435
+ display: block;
436
+ }
437
+ span.run90 {
438
+ background-color: rgb(255, 206, 178);
439
+ display: block;
440
+ }
441
+ span.run91 {
442
+ background-color: rgb(255, 204, 178);
443
+ display: block;
444
+ }
445
+ span.run92 {
446
+ background-color: rgb(255, 201, 178);
447
+ display: block;
448
+ }
449
+ span.run93 {
450
+ background-color: rgb(255, 198, 178);
451
+ display: block;
452
+ }
453
+ span.run94 {
454
+ background-color: rgb(255, 196, 178);
455
+ display: block;
456
+ }
457
+ span.run95 {
458
+ background-color: rgb(255, 192, 178);
459
+ display: block;
460
+ }
461
+ span.run96 {
462
+ background-color: rgb(255, 189, 178);
463
+ display: block;
464
+ }
465
+ span.run97 {
466
+ background-color: rgb(255, 187, 178);
467
+ display: block;
468
+ }
469
+ span.run98 {
470
+ background-color: rgb(255, 184, 178);
471
+ display: block;
472
+ }
473
+ span.run99 {
474
+ background-color: rgb(255, 182, 178);
475
+ display: block;
476
+ }
477
+ span.run100 {
478
+ background-color: rgb(255, 178, 178);
479
+ display: block;
480
+ }
481
+ </style></head><body><h3>C0 code coverage information generated on Sun May 21 00:51:53 CEST 2006</h3><hr /><pre><span class='marked'>Marked code looks like this.
482
+ This line is also marked as covered.
483
+ </span><span class='inferred'>Lines considered as run by rcov, but not reported by Ruby, look like this.
484
+ </span><span class='false'>Finally, here&apos;s a line marked as not executed.
485
+ </span></pre> <table class='report'>
486
+ <thead>
487
+ <tr>
488
+ <td class='heading'>Name</td>
489
+ <td class='heading'>Total lines</td>
490
+ <td class='heading'>Lines of code</td>
491
+ <td class='heading'>Total coverage</td>
492
+ <td class='heading'>Code coverage</td>
493
+ </tr>
494
+ </thead>
495
+ <tbody>
496
+ <tr>
497
+ <td>
498
+ <a href='-home-rosejn-projects-icalendar-lib-icalendar-parser_rb.html'>/home/rosejn/projects/icalendar/lib/icalendar/parser.rb</a>
499
+ </td>
500
+ <td class='value'>
501
+ <tt>398</tt>
502
+ </td>
503
+ <td class='value'>
504
+ <tt>398</tt>
505
+ </td>
506
+ <td>
507
+ <table cellspacing='0' cellpadding='0' align='right'>
508
+ <tr>
509
+ <td>
510
+ <tt>67.8%</tt>&nbsp;</td>
511
+ <td>
512
+ <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
513
+ <tr>
514
+ <td class='covered' width='68' />
515
+ <td class='uncovered' width='32' />
516
+ </tr>
517
+ </table>
518
+ </td>
519
+ </tr>
520
+ </table>
521
+ </td>
522
+ <td>
523
+ <table cellspacing='0' cellpadding='0' align='right'>
524
+ <tr>
525
+ <td>
526
+ <tt>54.2%</tt>&nbsp;</td>
527
+ <td>
528
+ <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
529
+ <tr>
530
+ <td class='covered' width='54' />
531
+ <td class='uncovered' width='46' />
532
+ </tr>
533
+ </table>
534
+ </td>
535
+ </tr>
536
+ </table>
537
+ </td>
538
+ </tr>
539
+ </tbody>
540
+ </table><pre><span class="false"> 1 =begin
541
+ 2 Copyright (C) 2005 Jeff Rose
542
+ 3 Copyright (C) 2005 Sam Roberts
543
+ 4
544
+ 5 This library is free software; you can redistribute it and/or modify it
545
+ 6 under the same terms as the ruby language itself, see the file COPYING for
546
+ 7 details.
547
+ 8 =end
548
+ </span><span class="marked"> 9
549
+ 10 require 'date'
550
+ 11 require 'uri'
551
+ 12
552
+ 13 module Icalendar
553
+ 14 class Parser &lt; Icalendar::Base
554
+ 15 # date = date-fullyear [&quot;-&quot;] date-month [&quot;-&quot;] date-mday
555
+ 16 # date-fullyear = 4 DIGIT
556
+ 17 # date-month = 2 DIGIT
557
+ 18 # date-mday = 2 DIGIT
558
+ 19 DATE = '(\d\d\d\d)-?(\d\d)-?(\d\d)'
559
+ 20
560
+ 21 # time = time-hour [&quot;:&quot;] time-minute [&quot;:&quot;] time-second [time-secfrac] [time-zone]
561
+ 22 # time-hour = 2 DIGIT
562
+ 23 # time-minute = 2 DIGIT
563
+ 24 # time-second = 2 DIGIT
564
+ 25 # time-secfrac = &quot;,&quot; 1*DIGIT
565
+ 26 # time-zone = &quot;Z&quot; / time-numzone
566
+ 27 # time-numzome = sign time-hour [&quot;:&quot;] time-minute
567
+ 28 TIME = '(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?'
568
+ 29
569
+ 30 def initialize(src)
570
+ 31 @@logger.debug(&quot;New Calendar Parser&quot;)
571
+ 32
572
+ 33 # Setup the parser method hash table
573
+ 34 setup_parsers()
574
+ 35
575
+ 36 # Define the next line method different depending on whether
576
+ 37 # this is a string or an IO object so we can be efficient about
577
+ 38 # parsing large files...
578
+ 39
579
+ 40 # Just do the unfolding work in one shot if its a whole string
580
+ 41 if src.respond_to?(:split)
581
+ 42 unfolded = []
582
+ 43
583
+ 44 # Split into an array of lines, then unfold those into a new array
584
+ 45 src.split(/\r?\n/).each do |line|
585
+ 46
586
+ 47 # If it's a continuation line, add it to the last.
587
+ 48 # If it's an empty line, drop it from the input.
588
+ 49 if( line =~ /^[ \t]/ )
589
+ </span><span class="false"> 50 unfolded &lt;&lt; unfolded.pop + line[1, line.size-1]
590
+ </span><span class="marked"> 51 elsif( line =~ /^$/ )
591
+ 52 else
592
+ 53 unfolded &lt;&lt; line
593
+ 54 end
594
+ 55 end
595
+ 56
596
+ 57 @lines = unfolded
597
+ 58 @index = 0
598
+ 59
599
+ 60 # Now that we are unfolded we can just iterate through the array.
600
+ 61 # Dynamically define next line for a string.
601
+ 62 def next_line
602
+ 63 if @index == @lines.size
603
+ 64 return nil
604
+ 65 else
605
+ 66 line = @lines[@index]
606
+ 67 @index += 1
607
+ 68 return line
608
+ 69 end
609
+ 70 end
610
+ 71
611
+ 72 # If its a file we need to read and unfold on the go to save from reading
612
+ 73 # large amounts of data into memory.
613
+ 74 elsif src.respond_to?(:gets)
614
+ </span><span class="false"> 75 @file = src
615
+ 76 @prev_line = src.gets
616
+ 77 if !@prev_line.nil?
617
+ 78 @prev_line.chomp!
618
+ 79 end
619
+ 80
620
+ 81 # Dynamically define next line for an IO object
621
+ 82 def next_line
622
+ 83 line = @prev_line
623
+ 84
624
+ 85 if line.nil?
625
+ 86 return nil
626
+ 87 end
627
+ 88
628
+ 89 # Loop through until we get to a non-continuation line...
629
+ 90 loop do
630
+ 91 nextLine = @file.gets
631
+ 92 if !nextLine.nil?
632
+ 93 nextLine.chomp!
633
+ 94 end
634
+ 95
635
+ 96 # If it's a continuation line, add it to the last.
636
+ 97 # If it's an empty line, drop it from the input.
637
+ 98 if( nextLine =~ /^[ \t]/ )
638
+ 99 line &lt;&lt; nextLine[1, nextLine.size]
639
+ 100 elsif( nextLine =~ /^$/ )
640
+ 101 else
641
+ 102 @prev_line = nextLine
642
+ 103 break
643
+ 104 end
644
+ 105 end
645
+ 106 line
646
+ 107 end
647
+ </span><span class="marked">108 else
648
+ 109 raise ArgumentError, &quot;CalendarParser.new cannot be called with a #{src.class} type!&quot;
649
+ 110 end
650
+ 111 end
651
+ 112
652
+ 113 # Parse the calendar into an object representation
653
+ 114 def parse
654
+ 115 calendars = []
655
+ 116
656
+ 117 # Outer loop for Calendar objects
657
+ 118 while (line = next_line)
658
+ 119 fields = parse_line(line)
659
+ 120
660
+ 121 # Just iterate through until we find the beginning of a calendar object
661
+ 122 if fields[:name] == &quot;BEGIN&quot; and fields[:value] == &quot;VCALENDAR&quot;
662
+ 123 cal = parse_component
663
+ 124 calendars &lt;&lt; cal
664
+ 125 end
665
+ 126 end
666
+ 127
667
+ 128 calendars
668
+ 129 end
669
+ 130
670
+ 131 private
671
+ 132
672
+ 133 # Parse a single VCALENDAR object
673
+ 134 # -- This should consist of the PRODID, VERSION, option METHOD &amp; CALSCALE,
674
+ 135 # and then one or more calendar components: VEVENT, VTODO, VJOURNAL,
675
+ 136 # VFREEBUSY, VTIMEZONE
676
+ 137 def parse_component(component = Calendar.new)
677
+ 138 while (line = next_line)
678
+ 139 fields = parse_line(line)
679
+ 140
680
+ 141 name = fields[:name].upcase
681
+ 142
682
+ 143 # Although properties are supposed to come before components, we should
683
+ 144 # be able to handle them in any order...
684
+ 145 if name == &quot;END&quot;
685
+ 146 break
686
+ 147 elsif name == &quot;BEGIN&quot; # New component
687
+ 148 case(fields[:value])
688
+ 149 when &quot;VEVENT&quot; # Event
689
+ 150 component.add_component parse_component(Event.new)
690
+ </span><span class="false">151 when &quot;VTODO&quot; # Todo entry
691
+ 152 component.add_component parse_component(Todo.new)
692
+ 153 when &quot;VALARM&quot; # Alarm sub-component for event and todo
693
+ 154 component.add_component parse_component(Alarm.new)
694
+ 155 when &quot;VJOURNAL&quot; # Journal entry
695
+ 156 component.add_component parse_component(Journal.new)
696
+ 157 when &quot;VFREEBUSY&quot; # Free/Busy section
697
+ 158 component.add_component parse_component(Freebusy.new)
698
+ 159 when &quot;VTIMEZONE&quot; # Timezone specification
699
+ 160 component.add_component parse_component(Timezone.new)
700
+ 161 when &quot;STANDARD&quot; # Standard time sub-component for timezone
701
+ 162 component.add_component parse_component(Standard.new)
702
+ 163 when &quot;DAYLIGHT&quot; # Daylight time sub-component for timezone
703
+ 164 component.add_component parse_component(Daylight.new)
704
+ 165 else # Uknown component type, skip to matching end
705
+ 166 until ((line = next_line) == &quot;END:#{fields[:value]}&quot;); end
706
+ 167 next
707
+ 168 end
708
+ </span><span class="marked">169 else # If its not a component then it should be a property
709
+ 170
710
+ 171 params = fields[:params]
711
+ 172 value = fields[:value]
712
+ 173
713
+ 174 # Lookup the property name to see if we have a string to
714
+ 175 # object parser for this property type.
715
+ 176 if @parsers.has_key?(name)
716
+ </span><span class="false">177 value = @parsers[name].call(name, params, value)
717
+ 178 end
718
+ </span><span class="marked">179
719
+ 180 name = name.downcase
720
+ 181
721
+ 182 # TODO: check to see if there are any more conflicts.
722
+ 183 if name == 'class' or name == 'method'
723
+ </span><span class="false">184 name = &quot;ip_&quot; + name
724
+ 185 end
725
+ </span><span class="marked">186
726
+ 187 # Replace dashes with underscores
727
+ 188 name = name.gsub('-', '_')
728
+ 189
729
+ 190 if component.multi_property?(name)
730
+ </span><span class="false">191 adder = &quot;add_&quot; + name
731
+ 192 if component.respond_to?(adder)
732
+ 193 component.send(adder, value, params)
733
+ 194 else
734
+ 195 raise(UnknownPropertyMethod, &quot;Unknown property type: #{adder}&quot;)
735
+ 196 end
736
+ </span><span class="marked">197 else
737
+ 198 if component.respond_to?(name)
738
+ 199 component.send(name, value, params)
739
+ </span><span class="false">200 else
740
+ 201 raise(UnknownPropertyMethod, &quot;Unknown property type: #{name}&quot;)
741
+ 202 end
742
+ 203 end
743
+ 204 end
744
+ 205 end
745
+ </span><span class="marked">206
746
+ 207 component
747
+ 208 end
748
+ 209
749
+ 210 # 1*(ALPHA / DIGIT / &quot;=&quot;)
750
+ 211 NAME = '[-a-z0-9]+'
751
+ 212
752
+ 213 # &lt;&quot;&gt; &lt;Any character except CTLs, DQUOTE&gt; &lt;&quot;&gt;
753
+ 214 QSTR = '&quot;[^&quot;]*&quot;'
754
+ 215
755
+ 216 # Contentline
756
+ 217 LINE = &quot;(#{NAME})(.*(?:#{QSTR})|(?:[^:]*))\:(.*)&quot;
757
+ 218
758
+ 219 # *&lt;Any character except CTLs, DQUOTE, &quot;;&quot;, &quot;:&quot;, &quot;,&quot;&gt;
759
+ 220 PTEXT = '[^&quot;;:,]*'
760
+ 221
761
+ 222 # param-value = ptext / quoted-string
762
+ 223 PVALUE = &quot;#{QSTR}|#{PTEXT}&quot;
763
+ 224
764
+ 225 # param = name &quot;=&quot; param-value *(&quot;,&quot; param-value)
765
+ 226 PARAM = &quot;;(#{NAME})(=?)((?:#{PVALUE})(?:,#{PVALUE})*)&quot;
766
+ 227
767
+ 228 def parse_line(line)
768
+ 229 unless line =~ %r{#{LINE}}i # Case insensitive match for a valid line
769
+ 230 raise &quot;Invalid line in calendar string!&quot;
770
+ 231 end
771
+ 232
772
+ 233 name = $1.upcase # The case insensitive part is upcased for easier comparison...
773
+ 234 paramslist = $2
774
+ 235 value = $3
775
+ 236
776
+ 237 # Parse the parameters
777
+ 238 params = {}
778
+ 239 if paramslist.size &gt; 1
779
+ 240 paramslist.scan( %r{#{PARAM}}i ) do
780
+ 241
781
+ 242 # parameter names are case-insensitive, and multi-valued
782
+ 243 pname = $1
783
+ 244 pvals = $3
784
+ 245
785
+ 246 # If their isn't an '=' sign then we need to do some custom
786
+ 247 # business. Defaults to 'type'
787
+ 248 if $2 == &quot;&quot;
788
+ </span><span class="false">249 pvals = $1
789
+ 250 case $1
790
+ 251 when /quoted-printable/i
791
+ 252 pname = 'encoding'
792
+ 253
793
+ 254 when /base64/i
794
+ 255 pname = 'encoding'
795
+ 256
796
+ 257 else
797
+ 258 pname = 'type'
798
+ 259 end
799
+ 260 end
800
+ </span><span class="marked">261
801
+ 262 # Make entries into the params dictionary where the name
802
+ 263 # is the key and the value is an array of values.
803
+ 264 unless params.key? pname
804
+ 265 params[pname] = []
805
+ 266 end
806
+ 267
807
+ 268 # Save all the values into the array.
808
+ 269 pvals.scan( %r{(#{PVALUE})} ) do
809
+ 270 if $1.size &gt; 0
810
+ 271 params[pname] &lt;&lt; $1
811
+ 272 end
812
+ 273 end
813
+ 274 end
814
+ 275 end
815
+ 276
816
+ 277 {:name =&gt; name, :value =&gt; value, :params =&gt; params}
817
+ 278 end
818
+ 279
819
+ 280 ## Following is a collection of parsing functions for various
820
+ 281 ## icalendar property value data types... First we setup
821
+ 282 ## a hash with property names pointing to methods...
822
+ 283 def setup_parsers
823
+ 284 @parsers = {}
824
+ 285
825
+ 286 # Integer properties
826
+ 287 m = self.method(:parse_integer)
827
+ 288 @parsers[&quot;PERCENT-COMPLETE&quot;] = m
828
+ 289 @parsers[&quot;PRIORITY&quot;] = m
829
+ 290 @parsers[&quot;REPEAT&quot;] = m
830
+ 291 @parsers[&quot;SEQUENCE&quot;] = m
831
+ 292
832
+ 293 # Dates and Times
833
+ 294 m = self.method(:parse_datetime)
834
+ 295 @parsers[&quot;COMPLETED&quot;] = m
835
+ 296 @parsers[&quot;DTEND&quot;] = m
836
+ 297 @parsers[&quot;DUE&quot;] = m
837
+ 298 @parsers[&quot;DTSTART&quot;] = m
838
+ 299 @parsers[&quot;RECURRENCE-ID&quot;] = m
839
+ 300 @parsers[&quot;EXDATE&quot;] = m
840
+ 301 @parsers[&quot;RDATE&quot;] = m
841
+ 302 @parsers[&quot;CREATED&quot;] = m
842
+ 303 @parsers[&quot;DTSTAMP&quot;] = m
843
+ 304 @parsers[&quot;LAST-MODIFIED&quot;] = m
844
+ 305
845
+ 306 # URI's
846
+ 307 m = self.method(:parse_uri)
847
+ 308 @parsers[&quot;TZURL&quot;] = m
848
+ 309 @parsers[&quot;ATTENDEE&quot;] = m
849
+ 310 @parsers[&quot;ORGANIZER&quot;] = m
850
+ 311 @parsers[&quot;URL&quot;] = m
851
+ 312
852
+ 313 # This is a URI by default, and if its not a valid URI
853
+ 314 # it will be returned as a string which works for binary data
854
+ 315 # the other possible type.
855
+ 316 @parsers[&quot;ATTACH&quot;] = m
856
+ 317
857
+ 318 # GEO
858
+ 319 m = self.method(:parse_geo)
859
+ 320 @parsers[&quot;GEO&quot;] = m
860
+ 321
861
+ 322 end
862
+ 323
863
+ 324 # Booleans
864
+ 325 # NOTE: It appears that although this is a valid data type
865
+ 326 # there aren't any properties that use it... Maybe get
866
+ 327 # rid of this in the future.
867
+ 328 def parse_boolean(name, params, value)
868
+ </span><span class="false">329 if value.upcase == &quot;FALSE&quot;
869
+ 330 false
870
+ 331 else
871
+ 332 true
872
+ 333 end
873
+ 334 end
874
+ </span><span class="marked">335
875
+ 336 # Dates, Date-Times &amp; Times
876
+ 337 # NOTE: invalid dates &amp; times will be returned as strings...
877
+ 338 def parse_datetime(name, params, value)
878
+ </span><span class="false">339 begin
879
+ 340 DateTime.parse(value)
880
+ 341 rescue Exception
881
+ 342 value
882
+ 343 end
883
+ 344
884
+ 345 end
885
+ </span><span class="marked">346
886
+ 347 # Durations
887
+ 348 # TODO: Need to figure out the best way to represent durations
888
+ 349 # so just returning string for now.
889
+ 350 def parse_duration(name, params, value)
890
+ </span><span class="false">351 value
891
+ 352 end
892
+ </span><span class="marked">353
893
+ 354 # Floats
894
+ 355 # NOTE: returns 0.0 if it can't parse the value
895
+ 356 def parse_float(name, params, value)
896
+ </span><span class="false">357 value.to_f
897
+ 358 end
898
+ </span><span class="marked">359
899
+ 360 # Integers
900
+ 361 # NOTE: returns 0 if it can't parse the value
901
+ 362 def parse_integer(name, params, value)
902
+ </span><span class="false">363 value.to_i
903
+ 364 end
904
+ </span><span class="marked">365
905
+ 366 # Periods
906
+ 367 # TODO: Got to figure out how to represent periods also...
907
+ 368 def parse_period(name, params, value)
908
+ </span><span class="false">369 value
909
+ 370 end
910
+ </span><span class="marked">371
911
+ 372 # Calendar Address's &amp; URI's
912
+ 373 # NOTE: invalid URI's will be returned as strings...
913
+ 374 def parse_uri(name, params, value)
914
+ </span><span class="false">375 begin
915
+ 376 URI.parse(value)
916
+ 377 rescue Exception
917
+ 378 value
918
+ 379 end
919
+ 380 end
920
+ </span><span class="marked">381
921
+ 382 # Geographical location (GEO)
922
+ 383 # NOTE: returns an array with two floats (long &amp; lat)
923
+ 384 # if the parsing fails return the string
924
+ 385 def parse_geo(name, params, value)
925
+ </span><span class="false">386 strloc = value.split(';')
926
+ 387 if strloc.size != 2
927
+ 388 return value
928
+ 389 end
929
+ 390
930
+ 391 val = []
931
+ 392 val[0] = strloc[0].to_f
932
+ 393 val[1] = strloc[1].to_f
933
+ 394 val
934
+ 395 end
935
+ 396
936
+ 397 end
937
+ 398 end
938
+ </span></pre><hr /><p><a href='http://validator.w3.org/check/referer'><img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88' /></a><a href='http://jigsaw.w3.org/css-validator/check/referer'><img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px' /></a></p></body></html>