plist 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6419e8cb1fbfdc4d07ec54cf7ca8e2baf6ed33af
4
- data.tar.gz: a4c8aa0a95cc0ad9bf25b724963ca8493543a015
2
+ SHA256:
3
+ metadata.gz: d5fa8e33a6700467ad3d91f7513275c19e020433e4e66b9df83020e38d04c24b
4
+ data.tar.gz: 2c588eb552e98c74d99b47138434e09a4dc3965857f2a9eb6af84fa14926b2ff
5
5
  SHA512:
6
- metadata.gz: 973b6bed1abafcffd88e4e51bfa8c304ce38b37a60f9d1424e68360ccdb7b749368f13c645fe5827ca63c11396aa45b6f980b8ff2dac56123a86202ad50c00bf
7
- data.tar.gz: 623bd3fca1591131ca3cd8d0dc6a683b444f63ed9aec50a3dc257408de93c3686b45ef4484b34fa43d04d9ca118799b0d7af84734e4cc8fa751abd1ca8de24bb
6
+ metadata.gz: 4600738237509772e5a8a9299b370e8a3c611e5b5540a40889c4623a5e88c080515f177c2e74e49cf93a29df36afd9097da9787aa82d40af14f75fd076e5c68b
7
+ data.tar.gz: bf5f666db425a2b664fdbba0b81ae14d38a4d88035ca7a29b66c35bfb9b87defe3216b0bc1cc67e5c960f174ad97b2e47b290cc86aaca56cffc4e325265d43e2
@@ -2,10 +2,16 @@
2
2
 
3
3
  === Unreleased
4
4
 
5
- https://github.com/patsplat/plist/compare/v3.3.0...HEAD
5
+ https://github.com/patsplat/plist/compare/v3.4.0...HEAD
6
6
 
7
7
  * Your contribution here!
8
8
 
9
+ === 3.4.0 (2017-12-08)
10
+
11
+ https://github.com/patsplat/plist/compare/v3.3.0...v3.4.0
12
+
13
+ * Support custom indent string (https://github.com/patsplat/plist/pull/44)
14
+
9
15
  === 3.3.0 (2017-04-28)
10
16
 
11
17
  https://github.com/patsplat/plist/compare/dece870...v3.3.0
@@ -7,9 +7,14 @@ Plist is a library to manipulate Property List files, also known as plists. It
7
7
 
8
8
  == Usage
9
9
 
10
+ === Security considerations
11
+
12
+ Plist.parse_xml uses Marshal.load for <data/> attributes. If the <data/> attribute contains malicious data, an attacker can gain code execution.
13
+ You should never use Plist.parse_xml with untrusted plists!
14
+
10
15
  === Parsing
11
16
 
12
- result = Plist::parse_xml('path/to/example.plist')
17
+ result = Plist.parse_xml('path/to/example.plist')
13
18
 
14
19
  result.class
15
20
  => Hash
@@ -112,15 +117,32 @@ When you attempt to serialize a +MyFancyString+ object, the +to_plist_node+ meth
112
117
 
113
118
  If for whatever reason you can't add this method, your object will be serialized with <tt>Marshal.dump</tt> instead.
114
119
 
120
+ ==== Custom indent
121
+
122
+ You can customize the default indent foramt (default format is tab) or specify the indent format on each serialization. For example, if you want to reduce size of plist output, you can set the indent to <tt>nil</tt>.
123
+
124
+ An example to change default indent format:
125
+
126
+ Plist::Emit::DEFAULT_INDENT = nil
127
+
128
+ An example to specify indent format on dump:
129
+
130
+ Plist::Emit.dump({:foo => :bar}, false)
131
+ => "<dict>\n\t<key>foo</key>\n\t<string>bar</string>\n</dict>\n"
132
+
133
+ Plist::Emit.dump({:foo => :bar}, false, :indent => nil)
134
+ => "<dict>\n<key>foo</key>\n<string>bar</string>\n</dict>\n"
135
+
136
+
115
137
  == Links
116
138
 
117
- [Project Page] http://plist.rubyforge.org
118
- [GitHub] http://github.com/bleything/plist
119
- [RDoc] http://plist.rubyforge.org
139
+ [Rubygems] https://rubygems.org/gems/plist
140
+ [GitHub] https://github.com/bleything/plist
141
+ [RDoc] http://www.rubydoc.info/gems/plist
120
142
 
121
143
  == Credits
122
144
 
123
- plist is maintained by Ben Bleything <mailto:ben@bleything.net> and Patrick May <mailto:patrick@hexane.org>. Patrick wrote most of the code; Ben is a recent addition to the project, having merged in his plist generation library.
145
+ plist was authored by Ben Bleything <mailto:ben@bleything.net> and Patrick May <mailto:patrick@hexane.org>. Patrick wrote most of the code; Ben contributed his plist generation library. The project is currently maintained by @mattbrictson[https://github.com/mattbrictson].
124
146
 
125
147
  Other folks who have helped along the way:
126
148
 
@@ -129,6 +151,7 @@ Other folks who have helped along the way:
129
151
  [<b>Mat Schaffer</b>] who supplied code and test cases for <tt><data></tt> elements
130
152
  [<b>Michael Granger</b>] for encouragement and help
131
153
  [<b>Carsten Bormann, Chris Hoffman, Dana Contreras, Hongli Lai, Johan Sørensen</b>] for contributing Ruby 1.9.x compatibility fixes
154
+ And thank you to all of the other GitHub contributors[https://github.com/patsplat/plist/graphs/contributors] not mentioned here!
132
155
 
133
156
  == License and Copyright
134
157
 
@@ -16,6 +16,3 @@ require 'stringio'
16
16
  require 'plist/generator'
17
17
  require 'plist/parser'
18
18
  require 'plist/version'
19
-
20
- module Plist
21
- end
@@ -6,208 +6,216 @@
6
6
  # Distributed under the MIT License
7
7
  #
8
8
 
9
- module Plist; end
10
-
11
- # === Create a plist
12
- # You can dump an object to a plist in one of two ways:
13
- #
14
- # * <tt>Plist::Emit.dump(obj)</tt>
15
- # * <tt>obj.to_plist</tt>
16
- # * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+.
17
- #
18
- # The following Ruby classes are converted into native plist types:
19
- # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false
20
- # * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
21
- # * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
22
- # * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.
23
- #
24
- # For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below.
25
- module Plist::Emit
26
- # Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+.
27
- def to_plist(envelope = true)
28
- return Plist::Emit.dump(self, envelope)
29
- end
30
-
31
- # Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+.
32
- def save_plist(filename)
33
- Plist::Emit.save_plist(self, filename)
34
- end
35
-
36
- # The following Ruby classes are converted into native plist types:
37
- # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time
9
+ module Plist
10
+ # === Create a plist
11
+ # You can dump an object to a plist in one of two ways:
38
12
  #
39
- # Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes.
13
+ # * <tt>Plist::Emit.dump(obj)</tt>
14
+ # * <tt>obj.to_plist</tt>
15
+ # * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+.
40
16
  #
41
- # +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+.
17
+ # The following Ruby classes are converted into native plist types:
18
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false
19
+ # * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
20
+ # * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
21
+ # * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.
42
22
  #
43
- # The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment.
44
- def self.dump(obj, envelope = true)
45
- output = plist_node(obj)
23
+ # For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below.
24
+ module Emit
25
+ DEFAULT_INDENT = "\t"
26
+
27
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+.
28
+ def to_plist(envelope = true, options = {})
29
+ options = { :indent => DEFAULT_INDENT }.merge(options)
30
+ return Plist::Emit.dump(self, envelope, options)
31
+ end
46
32
 
47
- output = wrap(output) if envelope
33
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+.
34
+ def save_plist(filename, options = {})
35
+ options = { :indent => DEFAULT_INDENT }.merge(options)
36
+ Plist::Emit.save_plist(self, filename, options)
37
+ end
48
38
 
49
- return output
50
- end
39
+ # The following Ruby classes are converted into native plist types:
40
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time
41
+ #
42
+ # Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes.
43
+ #
44
+ # +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+.
45
+ #
46
+ # The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment.
47
+ def self.dump(obj, envelope = true, options = {})
48
+ options = { :indent => DEFAULT_INDENT }.merge(options)
49
+ output = plist_node(obj, options)
50
+
51
+ output = wrap(output) if envelope
52
+
53
+ return output
54
+ end
51
55
 
52
- # Writes the serialized object's plist to the specified filename.
53
- def self.save_plist(obj, filename)
54
- File.open(filename, 'wb') do |f|
55
- f.write(obj.to_plist)
56
+ # Writes the serialized object's plist to the specified filename.
57
+ def self.save_plist(obj, filename, options = {})
58
+ options = { :indent => DEFAULT_INDENT }.merge(options)
59
+ File.open(filename, 'wb') do |f|
60
+ f.write(obj.to_plist(true, options))
61
+ end
56
62
  end
57
- end
58
63
 
59
- private
60
- def self.plist_node(element)
61
- output = ''
62
-
63
- if element.respond_to? :to_plist_node
64
- output << element.to_plist_node
65
- else
66
- case element
67
- when Array
68
- if element.empty?
69
- output << "<array/>\n"
70
- else
71
- output << tag('array') {
72
- element.collect {|e| plist_node(e)}
73
- }
74
- end
75
- when Hash
76
- if element.empty?
77
- output << "<dict/>\n"
78
- else
79
- inner_tags = []
64
+ private
65
+ def self.plist_node(element, options = {})
66
+ options = { :indent => DEFAULT_INDENT }.merge(options)
67
+ output = ''
80
68
 
81
- element.keys.sort_by{|k| k.to_s }.each do |k|
82
- v = element[k]
83
- inner_tags << tag('key', CGI::escapeHTML(k.to_s))
84
- inner_tags << plist_node(v)
69
+ if element.respond_to? :to_plist_node
70
+ output << element.to_plist_node
71
+ else
72
+ case element
73
+ when Array
74
+ if element.empty?
75
+ output << "<array/>\n"
76
+ else
77
+ output << tag('array', '', options) {
78
+ element.collect {|e| plist_node(e, options)}
79
+ }
85
80
  end
86
-
87
- output << tag('dict') {
88
- inner_tags
89
- }
81
+ when Hash
82
+ if element.empty?
83
+ output << "<dict/>\n"
84
+ else
85
+ inner_tags = []
86
+
87
+ element.keys.sort_by{|k| k.to_s }.each do |k|
88
+ v = element[k]
89
+ inner_tags << tag('key', CGI.escapeHTML(k.to_s), options)
90
+ inner_tags << plist_node(v, options)
91
+ end
92
+
93
+ output << tag('dict', '', options) {
94
+ inner_tags
95
+ }
96
+ end
97
+ when true, false
98
+ output << "<#{element}/>\n"
99
+ when Time
100
+ output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'), options)
101
+ when Date # also catches DateTime
102
+ output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'), options)
103
+ when String, Symbol, Integer, Float
104
+ output << tag(element_type(element), CGI.escapeHTML(element.to_s), options)
105
+ when IO, StringIO
106
+ element.rewind
107
+ contents = element.read
108
+ # note that apple plists are wrapped at a different length then
109
+ # what ruby's base64 wraps by default.
110
+ # I used #encode64 instead of #b64encode (which allows a length arg)
111
+ # because b64encode is b0rked and ignores the length arg.
112
+ data = "\n"
113
+ Base64.encode64(contents).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
114
+ output << tag('data', data, options)
115
+ else
116
+ output << comment('The <data> element below contains a Ruby object which has been serialized with Marshal.dump.')
117
+ data = "\n"
118
+ Base64.encode64(Marshal.dump(element)).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
119
+ output << tag('data', data, options)
90
120
  end
91
- when true, false
92
- output << "<#{element}/>\n"
93
- when Time
94
- output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'))
95
- when Date # also catches DateTime
96
- output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'))
97
- when String, Symbol, Integer, Float
98
- output << tag(element_type(element), CGI::escapeHTML(element.to_s))
99
- when IO, StringIO
100
- element.rewind
101
- contents = element.read
102
- # note that apple plists are wrapped at a different length then
103
- # what ruby's base64 wraps by default.
104
- # I used #encode64 instead of #b64encode (which allows a length arg)
105
- # because b64encode is b0rked and ignores the length arg.
106
- data = "\n"
107
- Base64::encode64(contents).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
108
- output << tag('data', data)
109
- else
110
- output << comment( 'The <data> element below contains a Ruby object which has been serialized with Marshal.dump.' )
111
- data = "\n"
112
- Base64::encode64(Marshal.dump(element)).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
113
- output << tag('data', data )
114
121
  end
122
+
123
+ return output
115
124
  end
116
125
 
117
- return output
118
- end
126
+ def self.comment(content)
127
+ return "<!-- #{content} -->\n"
128
+ end
119
129
 
120
- def self.comment(content)
121
- return "<!-- #{content} -->\n"
122
- end
130
+ def self.tag(type, contents = '', options = {}, &block)
131
+ options = { :indent => DEFAULT_INDENT }.merge(options)
132
+ out = nil
123
133
 
124
- def self.tag(type, contents = '', &block)
125
- out = nil
134
+ if block_given?
135
+ out = IndentedString.new(options[:indent])
136
+ out << "<#{type}>"
137
+ out.raise_indent
126
138
 
127
- if block_given?
128
- out = IndentedString.new
129
- out << "<#{type}>"
130
- out.raise_indent
139
+ out << block.call
131
140
 
132
- out << block.call
141
+ out.lower_indent
142
+ out << "</#{type}>"
143
+ else
144
+ out = "<#{type}>#{contents.to_s}</#{type}>\n"
145
+ end
133
146
 
134
- out.lower_indent
135
- out << "</#{type}>"
136
- else
137
- out = "<#{type}>#{contents.to_s}</#{type}>\n"
147
+ return out.to_s
138
148
  end
139
149
 
140
- return out.to_s
141
- end
150
+ def self.wrap(contents)
151
+ output = ''
142
152
 
143
- def self.wrap(contents)
144
- output = ''
153
+ output << '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
154
+ output << '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
155
+ output << '<plist version="1.0">' + "\n"
145
156
 
146
- output << '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
147
- output << '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
148
- output << '<plist version="1.0">' + "\n"
157
+ output << contents
149
158
 
150
- output << contents
151
-
152
- output << '</plist>' + "\n"
153
-
154
- return output
155
- end
159
+ output << '</plist>' + "\n"
156
160
 
157
- def self.element_type(item)
158
- case item
159
- when String, Symbol
160
- 'string'
161
+ return output
162
+ end
161
163
 
162
- when Integer
163
- 'integer'
164
+ def self.element_type(item)
165
+ case item
166
+ when String, Symbol
167
+ 'string'
164
168
 
165
- when Float
166
- 'real'
169
+ when Integer
170
+ 'integer'
167
171
 
168
- else
169
- raise "Don't know about this data type... something must be wrong!"
170
- end
171
- end
172
- private
173
- class IndentedString #:nodoc:
174
- attr_accessor :indent_string
175
-
176
- def initialize(str = "\t")
177
- @indent_string = str
178
- @contents = ''
179
- @indent_level = 0
180
- end
172
+ when Float
173
+ 'real'
181
174
 
182
- def to_s
183
- return @contents
175
+ else
176
+ raise "Don't know about this data type... something must be wrong!"
177
+ end
184
178
  end
179
+ private
180
+ class IndentedString #:nodoc:
181
+ attr_accessor :indent_string
182
+
183
+ def initialize(str = "\t")
184
+ @indent_string = str
185
+ @contents = ''
186
+ @indent_level = 0
187
+ end
185
188
 
186
- def raise_indent
187
- @indent_level += 1
188
- end
189
+ def to_s
190
+ return @contents
191
+ end
189
192
 
190
- def lower_indent
191
- @indent_level -= 1 if @indent_level > 0
192
- end
193
+ def raise_indent
194
+ @indent_level += 1
195
+ end
193
196
 
194
- def <<(val)
195
- if val.is_a? Array
196
- val.each do |f|
197
- self << f
198
- end
199
- else
200
- # if it's already indented, don't bother indenting further
201
- unless val =~ /\A#{@indent_string}/
202
- indent = @indent_string * @indent_level
197
+ def lower_indent
198
+ @indent_level -= 1 if @indent_level > 0
199
+ end
203
200
 
204
- @contents << val.gsub(/^/, indent)
201
+ def <<(val)
202
+ if val.is_a? Array
203
+ val.each do |f|
204
+ self << f
205
+ end
205
206
  else
206
- @contents << val
207
- end
207
+ # if it's already indented, don't bother indenting further
208
+ unless val =~ /\A#{@indent_string}/
209
+ indent = @indent_string * @indent_level
208
210
 
209
- # it already has a newline, don't add another
210
- @contents << "\n" unless val =~ /\n$/
211
+ @contents << val.gsub(/^/, indent)
212
+ else
213
+ @contents << val
214
+ end
215
+
216
+ # it already has a newline, don't add another
217
+ @contents << "\n" unless val =~ /\n$/
218
+ end
211
219
  end
212
220
  end
213
221
  end
@@ -11,41 +11,41 @@
11
11
  # === Load a plist file
12
12
  # This is the main point of the library:
13
13
  #
14
- # r = Plist::parse_xml( filename_or_xml )
14
+ # r = Plist.parse_xml(filename_or_xml)
15
15
  module Plist
16
- # Note that I don't use these two elements much:
17
- #
18
- # + Date elements are returned as DateTime objects.
19
- # + Data elements are implemented as Tempfiles
20
- #
21
- # Plist::parse_xml will blow up if it encounters a Date element.
22
- # If you encounter such an error, or if you have a Date element which
23
- # can't be parsed into a Time object, please send your plist file to
24
- # plist@hexane.org so that I can implement the proper support.
25
- def Plist::parse_xml( filename_or_xml )
16
+ # Note that I don't use these two elements much:
17
+ #
18
+ # + Date elements are returned as DateTime objects.
19
+ # + Data elements are implemented as Tempfiles
20
+ #
21
+ # Plist.parse_xml will blow up if it encounters a Date element.
22
+ # If you encounter such an error, or if you have a Date element which
23
+ # can't be parsed into a Time object, please create an issue
24
+ # attaching your plist file at https://github.com/patsplat/plist/issues
25
+ # so folks can implement the proper support.
26
+ def self.parse_xml(filename_or_xml)
26
27
  listener = Listener.new
27
- #parser = REXML::Parsers::StreamParser.new(File.new(filename), listener)
28
+ # parser = REXML::Parsers::StreamParser.new(File.new(filename), listener)
28
29
  parser = StreamParser.new(filename_or_xml, listener)
29
30
  parser.parse
30
31
  listener.result
31
32
  end
32
33
 
33
34
  class Listener
34
- #include REXML::StreamListener
35
+ # include REXML::StreamListener
35
36
 
36
37
  attr_accessor :result, :open
37
38
 
38
39
  def initialize
39
40
  @result = nil
40
- @open = Array.new
41
+ @open = []
41
42
  end
42
43
 
43
-
44
44
  def tag_start(name, attributes)
45
- @open.push PTag::mappings[name].new
45
+ @open.push PTag.mappings[name].new
46
46
  end
47
47
 
48
- def text( contents )
48
+ def text(contents)
49
49
  @open.last.text = contents if @open.last
50
50
  end
51
51
 
@@ -60,11 +60,11 @@ module Plist
60
60
  end
61
61
 
62
62
  class StreamParser
63
- def initialize( plist_data_or_file, listener )
63
+ def initialize(plist_data_or_file, listener)
64
64
  if plist_data_or_file.respond_to? :read
65
65
  @xml = plist_data_or_file.read
66
66
  elsif File.exist? plist_data_or_file
67
- @xml = File.read( plist_data_or_file )
67
+ @xml = File.read(plist_data_or_file)
68
68
  else
69
69
  @xml = plist_data_or_file
70
70
  end
@@ -78,15 +78,14 @@ module Plist
78
78
  COMMENT_START = /\A<!--/
79
79
  COMMENT_END = /.*?-->/m
80
80
 
81
-
82
81
  def parse
83
- plist_tags = PTag::mappings.keys.join('|')
82
+ plist_tags = PTag.mappings.keys.join('|')
84
83
  start_tag = /<(#{plist_tags})([^>]*)>/i
85
84
  end_tag = /<\/(#{plist_tags})[^>]*>/i
86
85
 
87
86
  require 'strscan'
88
87
 
89
- @scanner = StringScanner.new( @xml )
88
+ @scanner = StringScanner.new(@xml)
90
89
  until @scanner.eos?
91
90
  if @scanner.scan(COMMENT_START)
92
91
  @scanner.scan(COMMENT_END)
@@ -132,22 +131,21 @@ module Plist
132
131
  end
133
132
 
134
133
  class PTag
135
- @@mappings = { }
136
- def PTag::mappings
137
- @@mappings
134
+ def self.mappings
135
+ @mappings ||= {}
138
136
  end
139
137
 
140
- def PTag::inherited( sub_class )
138
+ def self.inherited(sub_class)
141
139
  key = sub_class.to_s.downcase
142
- key.gsub!(/^plist::/, '' )
140
+ key.gsub!(/^plist::/, '')
143
141
  key.gsub!(/^p/, '') unless key == "plist"
144
142
 
145
- @@mappings[key] = sub_class
143
+ mappings[key] = sub_class
146
144
  end
147
145
 
148
146
  attr_accessor :text, :children
149
147
  def initialize
150
- @children = Array.new
148
+ @children = []
151
149
  end
152
150
 
153
151
  def to_ruby
@@ -163,7 +161,7 @@ module Plist
163
161
 
164
162
  class PDict < PTag
165
163
  def to_ruby
166
- dict = Hash.new
164
+ dict = {}
167
165
  key = nil
168
166
 
169
167
  children.each do |c|
@@ -181,13 +179,13 @@ module Plist
181
179
 
182
180
  class PKey < PTag
183
181
  def to_ruby
184
- CGI::unescapeHTML(text || '')
182
+ CGI.unescapeHTML(text || '')
185
183
  end
186
184
  end
187
185
 
188
186
  class PString < PTag
189
187
  def to_ruby
190
- CGI::unescapeHTML(text || '')
188
+ CGI.unescapeHTML(text || '')
191
189
  end
192
190
  end
193
191
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Plist
4
- VERSION = '3.3.0'.freeze
4
+ VERSION = '3.4.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plist
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Bleything
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-04-28 00:00:00.000000000 Z
12
+ date: 2017-12-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  version: '0'
96
96
  requirements: []
97
97
  rubyforge_project:
98
- rubygems_version: 2.6.11
98
+ rubygems_version: 2.7.3
99
99
  signing_key:
100
100
  specification_version: 4
101
101
  summary: All-purpose Property List manipulation library