openxml-package 0.2.9 → 0.3.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
2
  SHA1:
3
- metadata.gz: c894c5ccef5327f4463ca9ddd3401bc6f3aa7e27
4
- data.tar.gz: c34eb930e46eff3af421c9ac49bf0bedc78113d6
3
+ metadata.gz: d9d9d2bb9ed93cad6c56d2642cf32f5dec4a3196
4
+ data.tar.gz: 523d6f4d5e2c72c78f3a0210231d4e95cd98b38f
5
5
  SHA512:
6
- metadata.gz: 2e6418b2b1dadf17009690fbfc6ada8d12f3e5b31493d4df9299bff672b8756098bb11d32c5fb9d3fe59180c7ee2838cf77ac167ca49b9ba6fe3120988cf3749
7
- data.tar.gz: f2a422bb660b761956f6a76ec856697115cc0d9ecd08b8f138c6e4093a6a74a8e83d5e2fad8325f62fda30eb6ab88f7f767b5acaa31e976e2bc231774f353cc5
6
+ metadata.gz: d12159354e30a736f3b20694cde93ad3855ba4a5ac17146ef252c325262fe92aa4ddd292b9dcf6d851e329884a3feaf5587393802134e90411f80da2fd33b5f3
7
+ data.tar.gz: 9c8c076c937bfe168182dfe7ddae3f6b0efa6a6687607661949cfceb1dfe92fb7bacf3717a27532921fc8b05c6384e4f1cfbbc98afc5c71dc9b552170901a1cb
@@ -1,3 +1,3 @@
1
1
  module OpenXmlPackage
2
- VERSION = "0.2.9"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -13,6 +13,7 @@ module OpenXml
13
13
  def initialize(options={})
14
14
  @to_s_options = { with_xml: true }
15
15
 
16
+ @ns = nil
16
17
  @document = Ox::Document.new(
17
18
  encoding: "UTF-8",
18
19
  version: "1.0",
@@ -8,7 +8,7 @@ module OpenXml
8
8
  end
9
9
 
10
10
  def []=(attribute, value)
11
- namespace_def = attribute.downcase.to_s.match /^xmlns(?:\:(?<prefix>.*))?$/
11
+ namespace_def = attribute.downcase.to_s.match(/^xmlns(?:\:(?<prefix>.*))?$/)
12
12
  namespaces << namespace_def[:prefix].to_sym if namespace_def && namespace_def[:prefix]
13
13
  super
14
14
  end
@@ -0,0 +1,24 @@
1
+ require "openxml/has_properties"
2
+
3
+ module OpenXml
4
+ module ContainsProperties
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ include HasProperties
9
+ include InstanceMethods
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+
15
+ def property_xml(xml)
16
+ props = active_properties
17
+ return unless render_properties? props
18
+ props.each { |prop| prop.to_xml(xml) }
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -6,21 +6,20 @@ module OpenXml
6
6
 
7
7
  class << self
8
8
  attr_reader :property_name
9
- attr_reader :namespace
10
9
 
11
10
  def tag(*args)
12
11
  @tag = args.first if args.any?
13
- @tag
12
+ @tag ||= nil
14
13
  end
15
14
 
16
15
  def name(*args)
17
16
  @property_name = args.first if args.any?
18
- @name
17
+ @property_name ||= nil
19
18
  end
20
19
 
21
20
  def namespace(*args)
22
21
  @namespace = args.first if args.any?
23
- @namespace
22
+ @namespace ||= nil
24
23
  end
25
24
 
26
25
  end
@@ -6,9 +6,10 @@ module OpenXml
6
6
  end
7
7
 
8
8
  module ClassMethods
9
- def attribute(name, expects: nil, one_of: nil, in_range: nil, displays_as: nil, namespace: nil, matches: nil, deprecated: false)
10
- bad_names = %w(tag name namespace properties_tag)
11
- raise ArgumentError if bad_names.member? name
9
+
10
+ def attribute(name, expects: nil, one_of: nil, in_range: nil, displays_as: nil, namespace: nil, matches: nil, validation: nil, deprecated: false)
11
+ bad_names = %w{ tag name namespace properties_tag }
12
+ raise ArgumentError if bad_names.member? name.to_s
12
13
 
13
14
  attr_reader name
14
15
 
@@ -17,21 +18,35 @@ module OpenXml
17
18
  send(expects, value) unless expects.nil?
18
19
  matches?(value, matches) unless matches.nil?
19
20
  in_range?(value, in_range) unless in_range.nil?
21
+ validation.call(value) if validation.respond_to? :call
20
22
  instance_variable_set "@#{name}", value
21
23
  end
22
24
 
23
25
  camelized_name = name.to_s.gsub(/_([a-z])/i) { $1.upcase }.to_sym
24
- attributes[name] = [displays_as || camelized_name, namespace || @attribute_namespace]
26
+ attributes[name] = [displays_as || camelized_name, namespace || attribute_namespace]
25
27
  end
26
28
 
27
29
  def attributes
28
- @attributes ||= {}
30
+ @attributes ||= begin
31
+ if superclass.respond_to?(:attributes)
32
+ Hash[superclass.attributes.map { |name, attribute|
33
+ [ name, attribute.dup ]
34
+ }]
35
+ else
36
+ {}
37
+ end
38
+ end
29
39
  end
30
40
 
31
41
  def with_namespace(namespace, &block)
32
42
  @attribute_namespace = namespace
33
43
  instance_eval(&block)
34
44
  end
45
+
46
+ def attribute_namespace
47
+ @attribute_namespace ||= nil
48
+ end
49
+
35
50
  end
36
51
 
37
52
  def render?
@@ -49,7 +64,7 @@ module OpenXml
49
64
  display, namespace = options
50
65
  value = send(name)
51
66
  attr_name = "#{namespace}:#{display}"
52
- attr_name = "#{display}" if namespace.nil?
67
+ attr_name = display.to_s if namespace.nil?
53
68
  attrs[attr_name] = value unless value.nil?
54
69
  end
55
70
  end
@@ -110,7 +125,7 @@ module OpenXml
110
125
  end
111
126
 
112
127
  def on_or_off(value)
113
- valid_in? value, [:on, :off]
128
+ valid_in? value, %i{ on off }
114
129
  end
115
130
 
116
131
  def valid_in?(value, list)
@@ -2,7 +2,8 @@ module OpenXml
2
2
  module HasChildren
3
3
  attr_reader :children
4
4
 
5
- def initialize
5
+ def initialize(*)
6
+ super
6
7
  @children = []
7
8
  end
8
9
 
@@ -26,5 +27,6 @@ module OpenXml
26
27
  def render?
27
28
  super || children.any?
28
29
  end
30
+
29
31
  end
30
32
  end
@@ -0,0 +1,176 @@
1
+ module OpenXml
2
+ module HasProperties
3
+
4
+ class ChoiceGroupUniqueError < RuntimeError; end
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def properties_tag(*args)
13
+ @properties_tag = args.first if args.any?
14
+ @properties_tag ||= nil
15
+ end
16
+
17
+ def value_property(name, as: nil, klass: nil)
18
+ attr_reader name
19
+
20
+ properties[name] = (as || name).to_s
21
+ classified_name = properties[name].split("_").map(&:capitalize).join
22
+ class_name = klass.name unless klass.nil?
23
+ class_name ||= (to_s.split("::")[0...-2] + ["Properties", classified_name]).join("::")
24
+
25
+ (choice_groups[current_group] ||= []).push(name) unless current_group.nil?
26
+
27
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
28
+ def #{name}=(value)
29
+ group_index = #{@current_group.inspect}
30
+ ensure_unique_in_group(:#{name}, group_index) unless group_index.nil?
31
+ instance_variable_set "@#{name}", #{class_name}.new(value)
32
+ end
33
+ CODE
34
+ end
35
+
36
+ def property(name, as: nil, klass: nil)
37
+ properties[name] = (as || name).to_s
38
+ classified_name = properties[name].split("_").map(&:capitalize).join
39
+ class_name = klass.name unless klass.nil?
40
+ class_name ||= (to_s.split("::")[0...-2] + ["Properties", classified_name]).join("::")
41
+
42
+ (choice_groups[current_group] ||= []).push(name) unless current_group.nil?
43
+
44
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
45
+ def #{name}(*args)
46
+ if instance_variable_get("@#{name}").nil?
47
+ group_index = #{@current_group.inspect}
48
+ ensure_unique_in_group(:#{name}, group_index) unless group_index.nil?
49
+ instance_variable_set "@#{name}", #{class_name}.new(*args)
50
+ end
51
+
52
+ instance_variable_get "@#{name}"
53
+ end
54
+ CODE
55
+ end
56
+
57
+ def property_choice
58
+ @current_group = choice_groups.length
59
+ yield
60
+ @current_group = nil
61
+ end
62
+
63
+ def current_group
64
+ @current_group ||= nil
65
+ end
66
+
67
+ def properties
68
+ @properties ||= begin
69
+ if superclass.respond_to?(:properties)
70
+ Hash[superclass.properties.map { |key, klass_name| [ key, klass_name.dup ] }]
71
+ else
72
+ {}
73
+ end
74
+ end
75
+ end
76
+
77
+ def choice_groups
78
+ @choice_groups ||= begin
79
+ if superclass.respond_to?(:choice_groups)
80
+ superclass.choice_groups.map(&:dup)
81
+ else
82
+ []
83
+ end
84
+ end
85
+ end
86
+
87
+ def properties_attribute(name, **args)
88
+ properties_element.attribute name, **args
89
+ define_method "#{name}=" do |value|
90
+ properties_element.public_send :"#{name}=", value
91
+ end
92
+
93
+ define_method name.to_s do
94
+ properties_element.public_send name.to_sym
95
+ end
96
+ end
97
+
98
+ def properties_element
99
+ this = self
100
+ parent_klass = superclass.respond_to?(:properties_element) ? superclass.properties_element : OpenXml::Element
101
+ @properties_element ||= Class.new(parent_klass) do
102
+ tag :"#{this.properties_tag || this.default_properties_tag}"
103
+ namespace :"#{this.namespace}"
104
+ end
105
+ end
106
+
107
+ def default_properties_tag
108
+ :"#{tag}Pr"
109
+ end
110
+
111
+ end
112
+
113
+ def properties_element
114
+ @properties_element ||= self.class.properties_element.new
115
+ end
116
+
117
+ def properties_attributes
118
+ properties_element.attributes
119
+ end
120
+
121
+ def render?
122
+ return true unless defined?(super)
123
+ render_properties? || super
124
+ end
125
+
126
+ def to_xml(xml)
127
+ super(xml) do
128
+ property_xml(xml)
129
+ yield xml if block_given?
130
+ end
131
+ end
132
+
133
+ def property_xml(xml)
134
+ props = active_properties
135
+ return unless render_properties? props
136
+
137
+ properties_element.to_xml(xml) do
138
+ props.each { |prop| prop.to_xml(xml) }
139
+ end
140
+ end
141
+
142
+ private
143
+
144
+ def properties
145
+ self.class.properties
146
+ end
147
+
148
+ def active_properties
149
+ properties.keys.map { |property| instance_variable_get("@#{property}") }.compact
150
+ end
151
+
152
+ def render_properties?(properties=active_properties)
153
+ properties.any?(&:render?) || properties_attributes.any?
154
+ end
155
+
156
+ def properties_tag
157
+ self.class.properties_tag || default_properties_tag
158
+ end
159
+
160
+ def default_properties_tag
161
+ :"#{tag}Pr"
162
+ end
163
+
164
+ def choice_groups
165
+ self.class.choice_groups
166
+ end
167
+
168
+ def ensure_unique_in_group(name, group_index)
169
+ other_names = (choice_groups[group_index] - [name])
170
+ unique = other_names.all? { |other_name| instance_variable_defined?("@#{other_name}") }
171
+ message = "Property #{name} cannot also be set with #{other_names.join(", ")}."
172
+ raise ChoiceGroupUniqueError, message unless unique
173
+ end
174
+
175
+ end
176
+ end
@@ -18,7 +18,7 @@ module OpenXml
18
18
  end
19
19
 
20
20
  def content_types(&block)
21
- content_types_presets.instance_eval &block
21
+ content_types_presets.instance_eval(&block)
22
22
  end
23
23
 
24
24
  def open(path)
@@ -0,0 +1,22 @@
1
+ module OpenXml
2
+ module Properties
3
+ end
4
+ end
5
+
6
+ require "openxml/properties/base_property"
7
+ require "openxml/properties/complex_property"
8
+ require "openxml/properties/value_property"
9
+
10
+ require "openxml/properties/boolean_property"
11
+ require "openxml/properties/integer_property"
12
+ require "openxml/properties/positive_integer_property"
13
+ require "openxml/properties/string_property"
14
+ require "openxml/properties/on_off_property"
15
+ require "openxml/properties/toggle_property"
16
+
17
+ require "openxml/properties/container_property"
18
+ require "openxml/properties/transparent_container_property"
19
+
20
+ Dir.glob(File.join(File.dirname(__FILE__), "properties", "*.rb").to_s).each do |file|
21
+ require file
22
+ end
@@ -0,0 +1,81 @@
1
+ module OpenXml
2
+ module Properties
3
+ class BaseProperty
4
+ attr_reader :value
5
+
6
+ class << self
7
+ attr_reader :property_name
8
+ attr_reader :allowed_tags
9
+
10
+ def tag_is_one_of(tags)
11
+ attr_accessor :tag
12
+ @allowed_tags = tags
13
+ end
14
+
15
+ def tag(*args)
16
+ @tag = args.first if args.any?
17
+ @tag ||= nil
18
+ end
19
+
20
+ def name(*args)
21
+ @property_name = args.first if args.any?
22
+ @property_name ||= nil
23
+ end
24
+
25
+ def namespace(*args)
26
+ @namespace = args.first if args.any?
27
+ @namespace ||= nil
28
+ end
29
+
30
+ end
31
+
32
+ def initialize(tag=nil, *_args)
33
+ return unless self.class.allowed_tags
34
+ validate_tag tag
35
+ @tag = tag
36
+ end
37
+
38
+ def validate_tag(tag)
39
+ return if self.class.allowed_tags.include?(tag)
40
+ allowed = self.class.allowed_tags.join(", ")
41
+ message = "Invalid tag name for #{name}: #{tag.inspect}. It should be one of #{allowed}."
42
+ raise ArgumentError, message
43
+ end
44
+
45
+ def render?
46
+ !value.nil?
47
+ end
48
+
49
+ def name
50
+ self.class.property_name || default_name
51
+ end
52
+
53
+ def default_name
54
+ class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
55
+ end
56
+
57
+ def tag
58
+ self.class.tag || default_tag
59
+ end
60
+
61
+ def default_tag
62
+ (class_name[0, 1].downcase + class_name[1..-1]).to_sym
63
+ end
64
+
65
+ def namespace
66
+ self.class.namespace
67
+ end
68
+
69
+ private
70
+
71
+ def apply_namespace(xml)
72
+ namespace.nil? ? xml : xml[namespace]
73
+ end
74
+
75
+ def class_name
76
+ self.class.to_s.split(/::/).last
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,15 @@
1
+ module OpenXml
2
+ module Properties
3
+ class BooleanProperty < ValueProperty
4
+
5
+ def ok_values
6
+ [nil, true, false]
7
+ end
8
+
9
+ def to_xml(xml)
10
+ super if value
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require "openxml/has_attributes"
2
+
3
+ module OpenXml
4
+ module Properties
5
+ class ComplexProperty < BaseProperty
6
+ include HasAttributes
7
+
8
+ def to_xml(xml)
9
+ return unless render?
10
+ apply_namespace(xml).public_send(tag, xml_attributes) do
11
+ yield xml if block_given?
12
+ end
13
+ end
14
+
15
+ def render?
16
+ !xml_attributes.empty?
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,70 @@
1
+ require "openxml/has_attributes"
2
+
3
+ module OpenXml
4
+ module Properties
5
+ class ContainerProperty < BaseProperty
6
+ include Enumerable
7
+ include HasAttributes
8
+
9
+ class << self
10
+
11
+ def child_class(*args)
12
+ unless args.empty?
13
+ @child_classes = args.map { |arg|
14
+ prop_name = arg.to_s.split(/_/).map(&:capitalize).join # LazyCamelCase
15
+ const_name = (self.to_s.split(/::/)[0...-1] + [prop_name]).join("::")
16
+ Object.const_get const_name
17
+ }
18
+ end
19
+
20
+ @child_classes
21
+ end
22
+ alias child_classes child_class
23
+
24
+ end
25
+
26
+ def initialize
27
+ @children = []
28
+ end
29
+
30
+ def <<(child)
31
+ raise ArgumentError, invalid_child_message unless valid_child?(child)
32
+ children << child
33
+ end
34
+
35
+ def each(*args, &block)
36
+ children.each(*args, &block)
37
+ end
38
+
39
+ def render?
40
+ !children.length.zero?
41
+ end
42
+
43
+ def to_xml(xml)
44
+ return unless render?
45
+
46
+ apply_namespace(xml).public_send(tag, xml_attributes) {
47
+ each { |child| child.to_xml(xml) }
48
+ }
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :children
54
+
55
+ def invalid_child_message
56
+ class_name = self.class.to_s.split(/::/).last
57
+ "#{class_name} must be instances of one of the following: #{child_classes}"
58
+ end
59
+
60
+ def valid_child?(child)
61
+ child_classes.any? { |child_class| child.is_a?(child_class) }
62
+ end
63
+
64
+ def child_classes
65
+ self.class.child_classes
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,15 @@
1
+ module OpenXml
2
+ module Properties
3
+ class IntegerProperty < ValueProperty
4
+
5
+ def valid?
6
+ value.is_a? Integer
7
+ end
8
+
9
+ def invalid_message
10
+ "Invalid #{name}: must be an integer"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module OpenXml
2
+ module Properties
3
+ class OnOffProperty < ValueProperty
4
+
5
+ def ok_values
6
+ [true, false, :on, :off] # :on and :off are from the Transitional Spec
7
+ end
8
+
9
+ def to_xml(xml)
10
+ if value == true
11
+ apply_namespace(xml).public_send(tag) do
12
+ yield xml if block_given?
13
+ end
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module OpenXml
2
+ module Properties
3
+ class PositiveIntegerProperty < IntegerProperty
4
+
5
+ def valid?
6
+ super && value >= 0
7
+ end
8
+
9
+ def invalid_message
10
+ "Invalid #{name}: must be a positive integer"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module OpenXml
2
+ module Properties
3
+ class StringProperty < ValueProperty
4
+
5
+ def valid?
6
+ value.is_a?(String) && !value.length.zero?
7
+ end
8
+
9
+ def invalid_message
10
+ "Invalid value for #{name}; string expected (provided: #{value.inspect})"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module OpenXml
2
+ module Properties
3
+ class ToggleProperty < OnOffProperty
4
+ # Toggle properties are no different in representation than on/off properties;
5
+ # rather, the difference is in how they compose with one another (cf.
6
+ # Section 17.7.3). It's helpful, then, to retain the concept, but entirely
7
+ # unnecessary to duplicate implementation.
8
+ # cf. Section A.6.9 of the spec, and Section A.7.9 of the transitional spec.
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module OpenXml
2
+ module Properties
3
+ class TransparentContainerProperty < ContainerProperty
4
+
5
+ def to_xml(xml)
6
+ return unless render?
7
+ each { |child| child.to_xml(xml) }
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ module OpenXml
2
+ module Properties
3
+ class ValueProperty < BaseProperty
4
+ attr_reader :value
5
+
6
+ def initialize(value)
7
+ @value = value
8
+ raise ArgumentError, invalid_message unless valid?
9
+ end
10
+
11
+ def valid?
12
+ ok_values.member? value
13
+ end
14
+
15
+ def invalid_message
16
+ "#{value.inspect} is an invalid value for #{name}; acceptable: #{ok_values.join(", ")}"
17
+ end
18
+
19
+ def render?
20
+ !value.nil?
21
+ end
22
+
23
+ def to_xml(xml)
24
+ apply_namespace(xml).public_send(tag, :"#{value_attribute}" => value) do
25
+ yield xml if block_given?
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def value_attribute
32
+ namespace.nil? ? "val" : "#{namespace}:val"
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -4,10 +4,12 @@ module Zip
4
4
  class InputStream
5
5
  protected
6
6
 
7
+ alias _old_get_io get_io
8
+
7
9
  # The problem in RubyZip 1.1.0 is that we only call `seek`
8
10
  # when `io` is a File. We need to move the cursor to the
9
11
  # right position when `io` is a StringIO as well.
10
- def get_io(io, offset = 0)
12
+ def get_io(io, offset=0)
11
13
  io = ::File.open(io, "rb") unless io.is_a?(IO) || io.is_a?(StringIO)
12
14
  io.seek(offset, ::IO::SEEK_SET)
13
15
  io
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openxml-package
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Lail
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-13 00:00:00.000000000 Z
11
+ date: 2017-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -195,17 +195,31 @@ files:
195
195
  - lib/openxml-package/version.rb
196
196
  - lib/openxml/builder.rb
197
197
  - lib/openxml/builder/element.rb
198
+ - lib/openxml/contains_properties.rb
198
199
  - lib/openxml/content_types_presets.rb
199
200
  - lib/openxml/element.rb
200
201
  - lib/openxml/errors.rb
201
202
  - lib/openxml/has_attributes.rb
202
203
  - lib/openxml/has_children.rb
204
+ - lib/openxml/has_properties.rb
203
205
  - lib/openxml/package.rb
204
206
  - lib/openxml/part.rb
205
207
  - lib/openxml/parts.rb
206
208
  - lib/openxml/parts/content_types.rb
207
209
  - lib/openxml/parts/rels.rb
208
210
  - lib/openxml/parts/unparsed_part.rb
211
+ - lib/openxml/properties.rb
212
+ - lib/openxml/properties/base_property.rb
213
+ - lib/openxml/properties/boolean_property.rb
214
+ - lib/openxml/properties/complex_property.rb
215
+ - lib/openxml/properties/container_property.rb
216
+ - lib/openxml/properties/integer_property.rb
217
+ - lib/openxml/properties/on_off_property.rb
218
+ - lib/openxml/properties/positive_integer_property.rb
219
+ - lib/openxml/properties/string_property.rb
220
+ - lib/openxml/properties/toggle_property.rb
221
+ - lib/openxml/properties/transparent_container_property.rb
222
+ - lib/openxml/properties/value_property.rb
209
223
  - lib/openxml/relationship.rb
210
224
  - lib/openxml/rubyzip_fix.rb
211
225
  - lib/openxml/types.rb