vcard 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +15 -5
  2. data/Gemfile +3 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +17 -0
  5. data/Rakefile +4 -52
  6. data/{LICENSE → VPIM-LICENSE.txt} +2 -2
  7. data/lib/vcard.rb +304 -28
  8. data/lib/vcard/attachment.rb +10 -12
  9. data/lib/vcard/bnf.rb +66 -0
  10. data/lib/vcard/dirinfo.rb +24 -26
  11. data/lib/vcard/enumerator.rb +5 -7
  12. data/lib/vcard/errors.rb +23 -0
  13. data/lib/vcard/field.rb +56 -58
  14. data/lib/vcard/vcard.rb +210 -240
  15. data/lib/vcard/version.rb +3 -0
  16. data/test/field_test.rb +55 -55
  17. data/test/fixtures/bday_decode.vcard +3 -0
  18. data/test/fixtures/bday_decode_2.vcard +6 -0
  19. data/test/fixtures/empty_tel.vcard +3 -0
  20. data/test/fixtures/ex1.vcard +7 -0
  21. data/test/fixtures/ex2.vcard +9 -0
  22. data/test/fixtures/ex3.vcard +30 -0
  23. data/test/fixtures/ex_21.vcard +16 -0
  24. data/test/fixtures/ex_21_case0.vcard +15 -0
  25. data/test/fixtures/ex_apple1.vcard +13 -0
  26. data/test/fixtures/ex_attach.vcard +16 -0
  27. data/test/fixtures/ex_bdays.vcard +8 -0
  28. data/test/fixtures/ex_encode_1.vcard +10 -0
  29. data/test/fixtures/ex_ical_1.vcal +47 -0
  30. data/test/fixtures/gmail.vcard +27 -0
  31. data/test/fixtures/highrise.vcard +41 -0
  32. data/test/fixtures/multiple_occurences_of_type.vcard +17 -0
  33. data/test/fixtures/nickname0.vcard +2 -0
  34. data/test/fixtures/nickname1.vcard +3 -0
  35. data/test/fixtures/nickname2.vcard +3 -0
  36. data/test/fixtures/nickname3.vcard +3 -0
  37. data/test/fixtures/nickname4.vcard +4 -0
  38. data/test/fixtures/nickname5.vcard +5 -0
  39. data/test/fixtures/slash_in_field_name.vcard +3 -0
  40. data/test/fixtures/tst1.vcard +9 -0
  41. data/test/fixtures/url_decode.vcard +4 -0
  42. data/test/test_helper.rb +34 -6
  43. data/test/vcard_test.rb +87 -577
  44. data/vcard.gemspec +19 -0
  45. metadata +88 -43
  46. data/.document +0 -5
  47. data/README.rdoc +0 -7
  48. data/VERSION +0 -1
  49. data/lib/vcard/rfc2425.rb +0 -367
@@ -1,12 +1,10 @@
1
- =begin
2
- Copyright (C) 2008 Sam Roberts
1
+ # Copyright (C) 2008 Sam Roberts
3
2
 
4
- This library is free software; you can redistribute it and/or modify it
5
- under the same terms as the ruby language itself, see the file COPYING for
6
- details.
7
- =end
3
+ # This library is free software; you can redistribute it and/or modify
4
+ # it under the same terms as the ruby language itself, see the file
5
+ # LICENSE-VPIM.txt for details.
8
6
 
9
- module Vpim
7
+ module Vcard
10
8
 
11
9
  # Attachments are used by both iCalendar and vCard. They are either a URI or
12
10
  # inline data, and their decoded value will be either a Uri or a Inline, as
@@ -31,14 +29,14 @@ module Vpim
31
29
  # iCalendar and vCard put the format in different parameters, and the
32
30
  # default kind of value is different.
33
31
  def Attachment.decode(field, defkind, fmtparam) #:nodoc:
34
- format = field.pvalue(fmtparam) || ''
32
+ format = field.pvalue(fmtparam) || ""
35
33
  kind = field.kind || defkind
36
34
  case kind
37
- when 'text'
38
- Inline.new(Vpim.decode_text(field.value), format)
39
- when 'uri'
35
+ when "text"
36
+ Inline.new(::Vcard.decode_text(field.value), format)
37
+ when "uri"
40
38
  Uri.new(field.value_raw, format)
41
- when 'binary'
39
+ when "binary"
42
40
  Inline.new(field.value, format)
43
41
  else
44
42
  raise InvalidEncodingError, "Attachment of type #{kind} is not allowed"
@@ -0,0 +1,66 @@
1
+ # Copyright (C) 2008 Sam Roberts
2
+
3
+ # This library is free software; you can redistribute it and/or modify
4
+ # it under the same terms as the ruby language itself, see the file
5
+ # LICENSE-VPIM.txt for details.
6
+
7
+ module Vcard
8
+ # Contains regular expression strings for the EBNF of RFC 2425.
9
+ module Bnf #:nodoc:
10
+
11
+ # 1*(ALPHA / DIGIT / "-")
12
+ # Note: I think I can add A-Z here, and get rid of the "i" matches elsewhere.
13
+ # Note: added "_" to allowed because its produced by Notes (X-LOTUS-CHILD_UID:)
14
+ # Note: added "/" to allowed because its produced by KAddressBook (X-messaging/xmpp-All:)
15
+ # Note: added " " to allowed because its produced by highrisehq.com (X-GOOGLE TALK:)
16
+ NAME = "[-a-z0-9_/][-a-z0-9_/ ]*"
17
+
18
+ # <"> <Any character except CTLs, DQUOTE> <">
19
+ QSTR = '"([^"]*)"'
20
+
21
+ # *<Any character except CTLs, DQUOTE, ";", ":", ",">
22
+ PTEXT = '([^";:,]+)'
23
+
24
+ # param-value = ptext / quoted-string
25
+ PVALUE = "(?:#{QSTR}|#{PTEXT})"
26
+
27
+ # param = name "=" param-value *("," param-value)
28
+ # Note: v2.1 allows a type or encoding param-value to appear without the type=
29
+ # or the encoding=. This is hideous, but we try and support it, if there
30
+ # is no "=", then $2 will be "", and we will treat it as a v2.1 param.
31
+ PARAM = ";(#{NAME})(=?)((?:#{PVALUE})?(?:,#{PVALUE})*)"
32
+
33
+ # V3.0: contentline = [group "."] name *(";" param) ":" value
34
+ # V2.1: contentline = *( group "." ) name *(";" param) ":" value
35
+ #
36
+ # We accept the V2.1 syntax for backwards compatibility.
37
+ #LINE = "((?:#{NAME}\\.)*)?(#{NAME})([^:]*)\:(.*)"
38
+ LINE = "^((?:#{NAME}\\.)*)?(#{NAME})((?:#{PARAM})*):(.*)$"
39
+
40
+ # date = date-fullyear ["-"] date-month ["-"] date-mday
41
+ # date-fullyear = 4 DIGIT
42
+ # date-month = 2 DIGIT
43
+ # date-mday = 2 DIGIT
44
+ DATE = "(\d\d\d\d)-?(\d\d)-?(\d\d)"
45
+
46
+ # time = time-hour [":"] time-minute [":"] time-second [time-secfrac] [time-zone]
47
+ # time-hour = 2 DIGIT
48
+ # time-minute = 2 DIGIT
49
+ # time-second = 2 DIGIT
50
+ # time-secfrac = "," 1*DIGIT
51
+ # time-zone = "Z" / time-numzone
52
+ # time-numzone = sign time-hour [":"] time-minute
53
+ TIME = "(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?"
54
+
55
+ # integer = (["+"] / "-") 1*DIGIT
56
+ INTEGER = "[-+]?\d+"
57
+
58
+ # QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII
59
+ # ; Any character except CTLs and DQUOTE
60
+ QSAFECHAR = "[ \t\x21\x23-\x7e\x80-\xff]"
61
+
62
+ # SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-US-ASCII
63
+ # ; Any character except CTLs, DQUOTE, ";", ":", ","
64
+ SAFECHAR = "[ \t\x21\x23-\x2b\x2d-\x39\x3c-\x7e\x80-\xff]"
65
+ end
66
+ end
@@ -1,12 +1,10 @@
1
- =begin
2
- Copyright (C) 2008 Sam Roberts
1
+ # Copyright (C) 2008 Sam Roberts
3
2
 
4
- This library is free software; you can redistribute it and/or modify it
5
- under the same terms as the ruby language itself, see the file COPYING for
6
- details.
7
- =end
3
+ # This library is free software; you can redistribute it and/or modify
4
+ # it under the same terms as the ruby language itself, see the file
5
+ # LICENSE-VPIM.txt for details.
8
6
 
9
- module Vpim
7
+ module Vcard
10
8
  # An RFC 2425 directory info object.
11
9
  #
12
10
  # A directory information object is a sequence of fields. The basic
@@ -19,13 +17,13 @@ module Vpim
19
17
  #
20
18
  # Here's an example of encoding a simple vCard using the low-level APIs:
21
19
  #
22
- # card = Vpim::Vcard.create
23
- # card << Vpim::DirectoryInfo::Field.create('EMAIL', 'user.name@example.com', 'TYPE' => 'INTERNET' )
24
- # card << Vpim::DirectoryInfo::Field.create('URL', 'http://www.example.com/user' )
25
- # card << Vpim::DirectoryInfo::Field.create('FN', 'User Name' )
20
+ # card = Vcard::Vcard.create
21
+ # card << Vcard::DirectoryInfo::Field.create("EMAIL", "user.name@example.com", "TYPE" => "INTERNET" )
22
+ # card << Vcard::DirectoryInfo::Field.create("URL", "http://www.example.com/user" )
23
+ # card << Vcard::DirectoryInfo::Field.create("FN", "User Name" )
26
24
  # puts card.to_s
27
25
  #
28
- # Don't do it like that, use Vpim::Vcard::Maker.
26
+ # Don't do it like that, use Vcard::Vcard::Maker.
29
27
  class DirectoryInfo
30
28
  include Enumerable
31
29
 
@@ -35,7 +33,7 @@ module Vpim
35
33
  # specified, check the BEGIN/END fields.
36
34
  def initialize(fields, profile = nil) #:nodoc:
37
35
  if fields.detect { |f| ! f.kind_of? DirectoryInfo::Field }
38
- raise ArgumentError, 'fields must be an array of DirectoryInfo::Field objects'
36
+ raise ArgumentError, "fields must be an array of DirectoryInfo::Field objects"
39
37
  end
40
38
 
41
39
  @string = nil # this is used as a flag to indicate that recoding will be necessary
@@ -53,7 +51,7 @@ module Vpim
53
51
  # The lines in the string may be delimited using IETF (CRLF) or Unix (LF) conventions.
54
52
  #
55
53
  # A DirectoryInfo is mutable, you can add new fields to it, see
56
- # Vpim::DirectoryInfo::Field#create() for how to create a new Field.
54
+ # Vcard::DirectoryInfo::Field#create() for how to create a new Field.
57
55
  #
58
56
  # TODO: I don't believe this is ever used, maybe I can remove it.
59
57
  def DirectoryInfo.decode(card) #:nodoc:
@@ -67,7 +65,7 @@ module Vpim
67
65
  raise ArgumentError, "DirectoryInfo cannot be created from a #{card.type}"
68
66
  end
69
67
 
70
- fields = Vpim.decode(string)
68
+ fields = ::Vcard.decode(string)
71
69
 
72
70
  new(fields)
73
71
  end
@@ -84,9 +82,9 @@ module Vpim
84
82
 
85
83
  if profile
86
84
  p = profile.to_str
87
- f = [ Field.create('BEGIN', p) ]
85
+ f = [ Field.create("BEGIN", p) ]
88
86
  f.concat fields
89
- f.push Field.create('END', p)
87
+ f.push Field.create("END", p)
90
88
  fields = f
91
89
  end
92
90
 
@@ -103,7 +101,7 @@ module Vpim
103
101
  # The value of the first field named +name+, or nil if no
104
102
  # match is found.
105
103
  def [](name)
106
- enum_by_name(name).each { |f| return f.value if f.value != ''}
104
+ enum_by_name(name).each { |f| return f.value if f.value != ""}
107
105
  enum_by_name(name).each { |f| return f.value }
108
106
  nil
109
107
  end
@@ -153,11 +151,11 @@ module Vpim
153
151
  #
154
152
  # Print all the nicknames in a card:
155
153
  #
156
- # card.enum_by_name('NICKNAME') { |f| puts f.value }
154
+ # card.enum_by_name("NICKNAME") { |f| puts f.value }
157
155
  #
158
156
  # Print an Array of the preferred email addresses in the card:
159
157
  #
160
- # pref_emails = card.enum_by_name('EMAIL').select { |f| f.pref? }
158
+ # pref_emails = card.enum_by_name("EMAIL").select { |f| f.pref? }
161
159
  def enum_by_name(name)
162
160
  Enumerator.new(self, Proc.new { |field| field.name?(name) })
163
161
  end
@@ -172,9 +170,9 @@ module Vpim
172
170
  # end
173
171
  # end
174
172
  #
175
- # or to get an array of all the fields in group 'AGROUP', you could do:
173
+ # or to get an array of all the fields in group "AGROUP", you could do:
176
174
  #
177
- # card.enum_by_group('AGROUP').to_a
175
+ # card.enum_by_group("AGROUP").to_a
178
176
  def enum_by_group(group)
179
177
  Enumerator.new(self, Proc.new { |field| field.group?(group) })
180
178
  end
@@ -224,8 +222,8 @@ module Vpim
224
222
  # the Vcard::Maker examples.
225
223
  def delete(field)
226
224
  case
227
- when field.name?('BEGIN'), field.name?('END')
228
- raise ArgumentError, 'Cannot delete BEGIN or END fields.'
225
+ when field.name?("BEGIN"), field.name?("END")
226
+ raise ArgumentError, "Cannot delete BEGIN or END fields."
229
227
  else
230
228
  @fields.delete field
231
229
  end
@@ -251,10 +249,10 @@ module Vpim
251
249
  unless @fields.first
252
250
  raise "No fields to check"
253
251
  end
254
- unless @fields.first.name? 'BEGIN'
252
+ unless @fields.first.name? "BEGIN"
255
253
  raise "Needs BEGIN, found: #{@fields.first.encode nil}"
256
254
  end
257
- unless @fields.last.name? 'END'
255
+ unless @fields.last.name? "END"
258
256
  raise "Needs END, found: #{@fields.last.encode nil}"
259
257
  end
260
258
  unless @fields.last.value? @fields.first.value
@@ -1,12 +1,10 @@
1
- =begin
2
- Copyright (C) 2008 Sam Roberts
1
+ # Copyright (C) 2008 Sam Roberts
3
2
 
4
- This library is free software; you can redistribute it and/or modify it
5
- under the same terms as the ruby language itself, see the file COPYING for
6
- details.
7
- =end
3
+ # This library is free software; you can redistribute it and/or modify
4
+ # it under the same terms as the ruby language itself, see the file
5
+ # LICENSE-VPIM.txt for details.
8
6
 
9
- module Vpim
7
+ module Vcard
10
8
  # This is a way for an object to have multiple ways of being enumerated via
11
9
  # argument to it's #each() method. An Enumerator mixes in Enumerable, so the
12
10
  # standard APIs such as Enumerable#map(), Enumerable#to_a(), and
@@ -0,0 +1,23 @@
1
+ # Copyright (C) 2008 Sam Roberts
2
+
3
+ # This library is free software; you can redistribute it and/or modify
4
+ # it under the same terms as the ruby language itself, see the file
5
+ # LICENSE-VPIM.txt for details.
6
+
7
+ module Vcard
8
+ # Exception used to indicate that data being decoded is invalid, the message
9
+ # should describe what is invalid.
10
+ class InvalidEncodingError < StandardError; end
11
+
12
+ # Exception used to indicate that data being decoded is unsupported, the message
13
+ # should describe what is unsupported.
14
+ #
15
+ # If its unsupported, its likely because I didn't anticipate it being useful
16
+ # to support this, and it likely it could be supported on request.
17
+ class UnsupportedError < StandardError; end
18
+
19
+ # Exception used to indicate that encoding failed, probably because the
20
+ # object would not result in validly encoded data. The message should
21
+ # describe what is unsupported.
22
+ class Unencodeable < StandardError; end
23
+ end
@@ -1,12 +1,10 @@
1
- =begin
2
- Copyright (C) 2008 Sam Roberts
1
+ # Copyright (C) 2008 Sam Roberts
3
2
 
4
- This library is free software; you can redistribute it and/or modify it
5
- under the same terms as the ruby language itself, see the file COPYING for
6
- details.
7
- =end
3
+ # This library is free software; you can redistribute it and/or modify it
4
+ # under the same terms as the ruby language itself, see the file COPYING for
5
+ # details.
8
6
 
9
- module Vpim
7
+ module Vcard
10
8
 
11
9
  class DirectoryInfo
12
10
 
@@ -19,7 +17,7 @@ module Vpim
19
17
  # pvalue_iset/idel/iadd, where set sets them all, add adds if not present,
20
18
  # and del deletes any that are present
21
19
  # - I really, really, need a case-insensitive string...
22
- # - should allow nil as a field value, its not the same as '', if there is
20
+ # - should allow nil as a field value, its not the same as "", if there is
23
21
  # more than one pvalue, the empty string will show up. This isn't strictly
24
22
  # disallowed, but its odd. Should also strip empty strings on decoding, if
25
23
  # I don't already.
@@ -37,14 +35,14 @@ module Vpim
37
35
  end
38
36
 
39
37
  # Encode a field.
40
- def Field.encode0(group, name, params={}, value='') # :nodoc:
38
+ def Field.encode0(group, name, params={}, value="") # :nodoc:
41
39
  line = ""
42
40
 
43
41
  # A reminder of the line format:
44
42
  # [<group>.]<name>;<pname>=<pvalue>,<pvalue>:<value>
45
43
 
46
44
  if group
47
- line << group << '.'
45
+ line << group << "."
48
46
  end
49
47
 
50
48
  line << name
@@ -55,15 +53,15 @@ module Vpim
55
53
  pvalues = [ pvalues ]
56
54
  end
57
55
 
58
- line << ';' << pname << '='
56
+ line << ";" << pname << "="
59
57
 
60
- sep = "" # set to ',' after one pvalue has been appended
58
+ sep = "" # set to "," after one pvalue has been appended
61
59
 
62
60
  pvalues.each do |pvalue|
63
61
  # check if we need to do any encoding
64
- if pname.casecmp('ENCODING') == 0 && pvalue == :b64
65
- pvalue = 'B' # the RFC definition of the base64 param value
66
- value = [ value.to_str ].pack('m').gsub("\n", '')
62
+ if pname.casecmp("ENCODING") == 0 && pvalue == :b64
63
+ pvalue = "B" # the RFC definition of the base64 param value
64
+ value = [ value.to_str ].pack("m").gsub("\n", "")
67
65
  end
68
66
 
69
67
  line << sep << pvalue
@@ -71,7 +69,7 @@ module Vpim
71
69
  end
72
70
  end
73
71
 
74
- line << ':'
72
+ line << ":"
75
73
 
76
74
  line << Field.value_str(value)
77
75
 
@@ -79,16 +77,16 @@ module Vpim
79
77
  end
80
78
 
81
79
  def Field.value_str(value) # :nodoc:
82
- line = ''
80
+ line = ""
83
81
  case value
84
82
  when Date
85
- line << Vpim.encode_date(value)
83
+ line << ::Vcard.encode_date(value)
86
84
 
87
85
  when Time #, DateTime
88
- line << Vpim.encode_date_time(value)
86
+ line << ::Vcard.encode_date_time(value)
89
87
 
90
88
  when Array
91
- line << value.map { |v| Field.value_str(v) }.join(';')
89
+ line << value.map { |v| Field.value_str(v) }.join(";")
92
90
 
93
91
  when Symbol
94
92
  line << value
@@ -103,7 +101,7 @@ module Vpim
103
101
  # Decode a field.
104
102
  def Field.decode0(atline) # :nodoc:
105
103
  unless atline =~ %r{#{Bnf::LINE}}i
106
- raise Vpim::InvalidEncodingError, atline
104
+ raise ::Vcard::InvalidEncodingError, atline
107
105
  end
108
106
 
109
107
  atgroup = $1.upcase
@@ -117,7 +115,7 @@ module Vpim
117
115
  atvalue.strip!
118
116
 
119
117
  if atgroup.length > 0
120
- atgroup.chomp!('.')
118
+ atgroup.chomp!(".")
121
119
  else
122
120
  atgroup = nil
123
121
  end
@@ -134,21 +132,21 @@ module Vpim
134
132
  name = $1.upcase
135
133
  params = $3
136
134
 
137
- # v2.1 params have no '=' sign, figure out what kind of param it
138
- # is (either its a known encoding, or we treat it as a 'TYPE'
135
+ # v2.1 params have no "=" sign, figure out what kind of param it
136
+ # is (either its a known encoding, or we treat it as a "TYPE"
139
137
  # param).
140
138
 
141
139
  if $2 == ""
142
140
  params = $1
143
141
  case $1
144
142
  when /quoted-printable/i
145
- name = 'ENCODING'
143
+ name = "ENCODING"
146
144
 
147
145
  when /base64/i
148
- name = 'ENCODING'
146
+ name = "ENCODING"
149
147
 
150
148
  else
151
- name = 'TYPE'
149
+ name = "TYPE"
152
150
  end
153
151
  end
154
152
 
@@ -188,16 +186,16 @@ module Vpim
188
186
  # name (a String) to either a single string or symbol, or an array of
189
187
  # strings and symbols (parameters can be multi-valued).
190
188
  #
191
- # If 'ENCODING' => :b64 is specified as a parameter, the value will be
189
+ # If "ENCODING" => :b64 is specified as a parameter, the value will be
192
190
  # base-64 encoded. If it's already base-64 encoded, then use String
193
- # values ('ENCODING' => 'B'), and no further encoding will be done by
191
+ # values ("ENCODING" => "B"), and no further encoding will be done by
194
192
  # this routine.
195
193
  #
196
194
  # Currently handled value types are:
197
195
  # - Time, encoded as a date-time value
198
196
  # - Date, encoded as a date value
199
197
  # - String, encoded directly
200
- # - Array of String, concatentated with ';' between them.
198
+ # - Array of String, concatentated with ";" between them.
201
199
  #
202
200
  # TODO - need a way to encode String values as TEXT, at least optionally,
203
201
  # so as to escape special chars, etc.
@@ -206,7 +204,7 @@ module Vpim
206
204
 
207
205
  begin
208
206
  new(line)
209
- rescue Vpim::InvalidEncodingError => e
207
+ rescue ::Vcard::InvalidEncodingError => e
210
208
  raise ArgumentError, e.to_s
211
209
  end
212
210
  end
@@ -236,7 +234,7 @@ module Vpim
236
234
  l = l.gsub(/.{#{width},#{width}}/) { |m| m + "\n " }
237
235
  end
238
236
  # Make sure it's terminated with no more than a single NL.
239
- l.gsub(/\s*\z/, '') + "\n"
237
+ l.gsub(/\s*\z/, "") + "\n"
240
238
  end
241
239
 
242
240
  alias to_s encode
@@ -306,17 +304,17 @@ module Vpim
306
304
  # if VALUE parameter is not present.
307
305
  def value
308
306
  case encoding
309
- when nil, '8BIT', '7BIT' then @value
307
+ when nil, "8BIT", "7BIT" then @value
310
308
 
311
309
  # Hack - if the base64 lines started with 2 SPC chars, which is invalid,
312
310
  # there will be extra spaces in @value. Since no SPC chars show up in
313
311
  # b64 encodings, they can be safely stripped out before unpacking.
314
- when 'B', 'BASE64' then @value.gsub(' ', '').unpack('m*').first
312
+ when "B", "BASE64" then @value.gsub(" ", "").unpack("m*").first
315
313
 
316
- when 'QUOTED-PRINTABLE' then @value.unpack('M*').first
314
+ when "QUOTED-PRINTABLE" then @value.unpack("M*").first
317
315
 
318
316
  else
319
- raise Vpim::InvalidEncodingError, "unrecognized encoding (#{encoding})"
317
+ raise ::Vcard::InvalidEncodingError, "unrecognized encoding (#{encoding})"
320
318
  end
321
319
  end
322
320
 
@@ -360,7 +358,7 @@ module Vpim
360
358
  def type?(type)
361
359
  type = type.to_str
362
360
 
363
- types = param('TYPE')
361
+ types = param("TYPE")
364
362
 
365
363
  if types
366
364
  types = types.detect { |t| t.casecmp(type) == 0 }
@@ -368,18 +366,18 @@ module Vpim
368
366
  end
369
367
 
370
368
  # Is this field marked as preferred? A vCard field is preferred if
371
- # #type?('PREF'). This method is not necessarily meaningful for
369
+ # #type?("PREF"). This method is not necessarily meaningful for
372
370
  # non-vCard profiles.
373
371
  def pref?
374
- type? 'PREF'
372
+ type? "PREF"
375
373
  end
376
374
 
377
375
  # Set whether a field is marked as preferred. See #pref?
378
376
  def pref=(ispref)
379
377
  if ispref
380
- pvalue_iadd('TYPE', 'PREF')
378
+ pvalue_iadd("TYPE", "PREF")
381
379
  else
382
- pvalue_idel('TYPE', 'PREF')
380
+ pvalue_idel("TYPE", "PREF")
383
381
  end
384
382
  end
385
383
 
@@ -392,11 +390,11 @@ module Vpim
392
390
  # The value of the ENCODING parameter, if present, or nil if not
393
391
  # present.
394
392
  def encoding
395
- e = param('ENCODING')
393
+ e = param("ENCODING")
396
394
 
397
395
  if e
398
396
  if e.length > 1
399
- raise Vpim::InvalidEncodingError, "multi-valued param 'ENCODING' (#{e})"
397
+ raise ::Vcard::InvalidEncodingError, "multi-valued param 'ENCODING' (#{e})"
400
398
  end
401
399
  e = e.first.upcase
402
400
  end
@@ -406,7 +404,7 @@ module Vpim
406
404
  # The type of the value, as specified by the VALUE parameter, nil if
407
405
  # unspecified.
408
406
  def kind
409
- v = param('VALUE')
407
+ v = param("VALUE")
410
408
  if v
411
409
  if v.size > 1
412
410
  raise InvalidEncodingError, "multi-valued param 'VALUE' (#{values})"
@@ -430,7 +428,7 @@ module Vpim
430
428
  # its ridiculous! I think I need my own DateTime variant.
431
429
  def to_time
432
430
  begin
433
- Vpim.decode_date_time_list(value).collect do |d|
431
+ ::Vcard.decode_date_time_list(value).collect do |d|
434
432
  # We get [ year, month, day, hour, min, sec, usec, tz ]
435
433
  begin
436
434
  if(d.pop == "Z")
@@ -439,16 +437,16 @@ module Vpim
439
437
  Time.local(*d)
440
438
  end
441
439
  rescue ArgumentError => e
442
- raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
440
+ raise ::Vcard::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
443
441
  end
444
442
  end
445
- rescue Vpim::InvalidEncodingError
446
- Vpim.decode_date_list(value).collect do |d|
443
+ rescue ::Vcard::InvalidEncodingError
444
+ ::Vcard.decode_date_list(value).collect do |d|
447
445
  # We get [ year, month, day ]
448
446
  begin
449
447
  Time.gm(*d)
450
448
  rescue ArgumentError => e
451
- raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
449
+ raise ::Vcard::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
452
450
  end
453
451
  end
454
452
  end
@@ -463,12 +461,12 @@ module Vpim
463
461
  # works an InvalidEncodingError will be raised.
464
462
  def to_date
465
463
  begin
466
- Vpim.decode_date_time_list(value).collect do |d|
464
+ ::Vcard.decode_date_time_list(value).collect do |d|
467
465
  # We get [ year, month, day, hour, min, sec, usec, tz ]
468
466
  Date.new(d[0], d[1], d[2])
469
467
  end
470
- rescue Vpim::InvalidEncodingError
471
- Vpim.decode_date_list(value).collect do |d|
468
+ rescue ::Vcard::InvalidEncodingError
469
+ ::Vcard.decode_date_list(value).collect do |d|
472
470
  # We get [ year, month, day ]
473
471
  Date.new(*d)
474
472
  end
@@ -479,11 +477,11 @@ module Vpim
479
477
  # characters, this method will strip them, if present.
480
478
  #
481
479
  # In theory, #value could also do this, but it would need to know that
482
- # the value is of type 'TEXT', and often for text values the 'VALUE'
480
+ # the value is of type "TEXT", and often for text values the "VALUE"
483
481
  # parameter is not present, so knowledge of the expected type of the
484
482
  # field is required from the decoder.
485
483
  def to_text
486
- Vpim.decode_text(value)
484
+ ::Vcard.decode_text(value)
487
485
  end
488
486
 
489
487
  # The undecoded value, see +value+.
@@ -516,10 +514,10 @@ module Vpim
516
514
  # currently has. See Field.create() for a description of +pvalue+.
517
515
  #
518
516
  # Example:
519
- # if field['TYPE']
520
- # field['TYPE'] << 'HOME'
517
+ # if field["TYPE"]
518
+ # field["TYPE"] << "HOME"
521
519
  # else
522
- # field['TYPE'] = [ 'HOME' ]
520
+ # field["TYPE"] = [ "HOME" ]
523
521
  # end
524
522
  #
525
523
  # TODO - this could be an alias to #pvalue_set
@@ -597,7 +595,7 @@ module Vpim
597
595
  begin
598
596
  @group, @name, @params, @value = Field.decode0(line)
599
597
  @line = line
600
- rescue Vpim::InvalidEncodingError => e
598
+ rescue ::Vcard::InvalidEncodingError => e
601
599
  raise ArgumentError, e.to_s
602
600
  end
603
601
  self