openxml-package 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|