openxml-package 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openxml-package/version.rb +1 -1
- data/lib/openxml/element.rb +69 -0
- data/lib/openxml/has_attributes.rb +127 -0
- data/lib/openxml/has_children.rb +30 -0
- data/lib/openxml/parts/rels.rb +6 -7
- data/lib/openxml/relationship.rb +9 -0
- data/openxml-package.gemspec +0 -1
- metadata +7 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c894c5ccef5327f4463ca9ddd3401bc6f3aa7e27
|
4
|
+
data.tar.gz: c34eb930e46eff3af421c9ac49bf0bedc78113d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e6418b2b1dadf17009690fbfc6ada8d12f3e5b31493d4df9299bff672b8756098bb11d32c5fb9d3fe59180c7ee2838cf77ac167ca49b9ba6fe3120988cf3749
|
7
|
+
data.tar.gz: f2a422bb660b761956f6a76ec856697115cc0d9ecd08b8f138c6e4093a6a74a8e83d5e2fad8325f62fda30eb6ab88f7f767b5acaa31e976e2bc231774f353cc5
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "openxml/has_attributes"
|
2
|
+
|
3
|
+
module OpenXml
|
4
|
+
class Element
|
5
|
+
include HasAttributes
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_reader :property_name
|
9
|
+
attr_reader :namespace
|
10
|
+
|
11
|
+
def tag(*args)
|
12
|
+
@tag = args.first if args.any?
|
13
|
+
@tag
|
14
|
+
end
|
15
|
+
|
16
|
+
def name(*args)
|
17
|
+
@property_name = args.first if args.any?
|
18
|
+
@name
|
19
|
+
end
|
20
|
+
|
21
|
+
def namespace(*args)
|
22
|
+
@namespace = args.first if args.any?
|
23
|
+
@namespace
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def tag
|
29
|
+
self.class.tag || default_tag
|
30
|
+
end
|
31
|
+
|
32
|
+
def name
|
33
|
+
self.class.property_name || default_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def namespace
|
37
|
+
([self.class] + self.class.ancestors).select { |klass| klass.respond_to?(:namespace) }.map(&:namespace).find(&:itself)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_xml(xml)
|
41
|
+
raise UndefinedNamespaceError, self.class unless namespace
|
42
|
+
|
43
|
+
xml[namespace].public_send(tag, xml_attributes) do
|
44
|
+
yield xml if block_given?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def default_tag
|
51
|
+
(class_name[0, 1].downcase + class_name[1..-1]).to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
def default_name
|
55
|
+
class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
56
|
+
end
|
57
|
+
|
58
|
+
def class_name
|
59
|
+
self.class.to_s.split(/::/).last
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
class UndefinedNamespaceError < RuntimeError
|
65
|
+
def initialize(klass)
|
66
|
+
super "#{klass} does not define its namespace"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module HasAttributes
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
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
|
12
|
+
|
13
|
+
attr_reader name
|
14
|
+
|
15
|
+
define_method "#{name}=" do |value|
|
16
|
+
valid_in?(value, one_of) unless one_of.nil?
|
17
|
+
send(expects, value) unless expects.nil?
|
18
|
+
matches?(value, matches) unless matches.nil?
|
19
|
+
in_range?(value, in_range) unless in_range.nil?
|
20
|
+
instance_variable_set "@#{name}", value
|
21
|
+
end
|
22
|
+
|
23
|
+
camelized_name = name.to_s.gsub(/_([a-z])/i) { $1.upcase }.to_sym
|
24
|
+
attributes[name] = [displays_as || camelized_name, namespace || @attribute_namespace]
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes
|
28
|
+
@attributes ||= {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def with_namespace(namespace, &block)
|
32
|
+
@attribute_namespace = namespace
|
33
|
+
instance_eval(&block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def render?
|
38
|
+
attributes.keys.map(&method(:send)).any?
|
39
|
+
end
|
40
|
+
|
41
|
+
def attributes
|
42
|
+
self.class.attributes
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def xml_attributes
|
48
|
+
attributes.each_with_object({}) do |(name, options), attrs|
|
49
|
+
display, namespace = options
|
50
|
+
value = send(name)
|
51
|
+
attr_name = "#{namespace}:#{display}"
|
52
|
+
attr_name = "#{display}" if namespace.nil?
|
53
|
+
attrs[attr_name] = value unless value.nil?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def boolean(value)
|
58
|
+
message = "Invalid #{name}: frame must be true or false"
|
59
|
+
raise ArgumentError, message unless [true, false].member? value
|
60
|
+
end
|
61
|
+
|
62
|
+
def hex_color(value)
|
63
|
+
message = "Invalid #{name}: must be :auto or a hex color, e.g. 4F1B8C"
|
64
|
+
raise ArgumentError, message unless value == :auto || value =~ /^[0-9A-F]{6}$/
|
65
|
+
end
|
66
|
+
|
67
|
+
def hex_digit(value)
|
68
|
+
message = "Invalid #{name}: must be a two-digit hex number, e.g. BF"
|
69
|
+
raise ArgumentError, message unless value =~ /^[0-9A-F]{2}$/
|
70
|
+
end
|
71
|
+
|
72
|
+
def hex_digit_4(value)
|
73
|
+
message = "Invalid #{name}: must be a four-digit hex number, e.g. BF12"
|
74
|
+
raise ArgumentError, message unless value =~ /^[0-9A-F]{4}$/
|
75
|
+
end
|
76
|
+
|
77
|
+
def long_hex_number(value)
|
78
|
+
message = "Invalid #{name}: must be an eight-digit hex number, e.g., FFAC0013"
|
79
|
+
raise ArgumentError, message unless value =~ /^[0-9A-F]{8}$/
|
80
|
+
end
|
81
|
+
|
82
|
+
def hex_string(value)
|
83
|
+
message = "Invalid #{name}: must be a string of hexadecimal numbers, e.g. FFA23C6E"
|
84
|
+
raise ArgumentError, message unless value =~ /^[0-9A-F]+$/
|
85
|
+
end
|
86
|
+
|
87
|
+
def integer(value)
|
88
|
+
message = "Invalid #{name}: must be an integer"
|
89
|
+
raise ArgumentError, message unless value.is_a?(Integer)
|
90
|
+
end
|
91
|
+
|
92
|
+
def positive_integer(value)
|
93
|
+
message = "Invalid #{name}: must be a positive integer"
|
94
|
+
raise ArgumentError, message unless value.is_a?(Integer) && value >= 0
|
95
|
+
end
|
96
|
+
|
97
|
+
def string(value)
|
98
|
+
message = "Invalid #{name}: must be a string"
|
99
|
+
raise ArgumentError, message if !value.is_a?(String) || value.length.zero?
|
100
|
+
end
|
101
|
+
|
102
|
+
def in_range?(value, range)
|
103
|
+
message = "Invalid #{name}: must be a number between #{range.begin} and #{range.end}"
|
104
|
+
raise ArgumentError, message unless range.include?(value.to_i)
|
105
|
+
end
|
106
|
+
|
107
|
+
def percentage(value)
|
108
|
+
message = "Invalid #{name}: must be a percentage"
|
109
|
+
raise ArgumentError, message unless value.is_a?(String) && value =~ /-?[0-9]+(\.[0-9]+)?%/ # Regex supplied in sec. 22.9.2.9 of Office Open XML docs
|
110
|
+
end
|
111
|
+
|
112
|
+
def on_or_off(value)
|
113
|
+
valid_in? value, [:on, :off]
|
114
|
+
end
|
115
|
+
|
116
|
+
def valid_in?(value, list)
|
117
|
+
message = "Invalid #{name}: must be one of #{list} (was #{value.inspect})"
|
118
|
+
raise ArgumentError, message unless list.member?(value)
|
119
|
+
end
|
120
|
+
|
121
|
+
def matches?(value, regexp)
|
122
|
+
message = "Value does not match #{regexp}"
|
123
|
+
raise ArgumentError, message unless value =~ regexp
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module HasChildren
|
3
|
+
attr_reader :children
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@children = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def <<(child)
|
10
|
+
children << child
|
11
|
+
end
|
12
|
+
|
13
|
+
def push(child)
|
14
|
+
children.push(child)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_xml(xml)
|
18
|
+
super(xml) do
|
19
|
+
yield xml if block_given?
|
20
|
+
children.each do |child|
|
21
|
+
child.to_xml(xml)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def render?
|
27
|
+
super || children.any?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/openxml/parts/rels.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "securerandom"
|
2
|
+
require "openxml/relationship"
|
2
3
|
require "nokogiri"
|
3
4
|
|
4
5
|
module OpenXml
|
@@ -23,11 +24,15 @@ module OpenXml
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def add_relationship(type, target, id=nil, target_mode=nil)
|
26
|
-
Relationship.new(type, target, id, target_mode).tap do |relationship|
|
27
|
+
OpenXml::Elements::Relationship.new(type, target, id, target_mode).tap do |relationship|
|
27
28
|
relationships.push relationship
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
def push(relationship)
|
33
|
+
relationships.push relationship
|
34
|
+
end
|
35
|
+
|
31
36
|
def each(&block)
|
32
37
|
relationships.each(&block)
|
33
38
|
end
|
@@ -48,12 +53,6 @@ module OpenXml
|
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
51
|
-
class Relationship < Struct.new(:type, :target, :id, :target_mode)
|
52
|
-
def initialize(type, target, id=nil, target_mode=nil)
|
53
|
-
super type, target, id || "R#{SecureRandom.hex}", target_mode
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
56
|
private
|
58
57
|
attr_reader :relationships
|
59
58
|
|
data/openxml-package.gemspec
CHANGED
@@ -25,7 +25,6 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.6"
|
27
27
|
spec.add_development_dependency "rake"
|
28
|
-
spec.add_development_dependency "rails", ">= 3.2", "< 5.0"
|
29
28
|
spec.add_development_dependency "minitest"
|
30
29
|
spec.add_development_dependency "minitest-reporters"
|
31
30
|
spec.add_development_dependency "minitest-reporters-turn_reporter"
|
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.
|
4
|
+
version: 0.2.9
|
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-
|
11
|
+
date: 2017-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -80,26 +80,6 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rails
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '3.2'
|
90
|
-
- - "<"
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: '5.0'
|
93
|
-
type: :development
|
94
|
-
prerelease: false
|
95
|
-
version_requirements: !ruby/object:Gem::Requirement
|
96
|
-
requirements:
|
97
|
-
- - ">="
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
version: '3.2'
|
100
|
-
- - "<"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '5.0'
|
103
83
|
- !ruby/object:Gem::Dependency
|
104
84
|
name: minitest
|
105
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -216,13 +196,17 @@ files:
|
|
216
196
|
- lib/openxml/builder.rb
|
217
197
|
- lib/openxml/builder/element.rb
|
218
198
|
- lib/openxml/content_types_presets.rb
|
199
|
+
- lib/openxml/element.rb
|
219
200
|
- lib/openxml/errors.rb
|
201
|
+
- lib/openxml/has_attributes.rb
|
202
|
+
- lib/openxml/has_children.rb
|
220
203
|
- lib/openxml/package.rb
|
221
204
|
- lib/openxml/part.rb
|
222
205
|
- lib/openxml/parts.rb
|
223
206
|
- lib/openxml/parts/content_types.rb
|
224
207
|
- lib/openxml/parts/rels.rb
|
225
208
|
- lib/openxml/parts/unparsed_part.rb
|
209
|
+
- lib/openxml/relationship.rb
|
226
210
|
- lib/openxml/rubyzip_fix.rb
|
227
211
|
- lib/openxml/types.rb
|
228
212
|
- openxml-package.gemspec
|
@@ -247,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
231
|
version: '0'
|
248
232
|
requirements: []
|
249
233
|
rubyforge_project:
|
250
|
-
rubygems_version: 2.
|
234
|
+
rubygems_version: 2.6.11
|
251
235
|
signing_key:
|
252
236
|
specification_version: 4
|
253
237
|
summary: A Ruby implementation of OpenXmlPackage from Microsoft's Open XML SDK
|