axlsx 1.0.14 → 1.0.15

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.
@@ -1,61 +1,152 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'digest'
2
3
  require 'base64'
3
4
  require 'openssl'
5
+
4
6
  module Axlsx
7
+
8
+ # The MsOffCrypto class implements ECMA-367 encryption based on the MS-OFF-CRYPTO specification
5
9
  class MsOffCrypto
6
10
 
7
- attr_reader :verifier
8
- attr_reader :key
11
+ # Creates a new MsOffCrypto Object
12
+ # @param [String] file_name the location of the file you want to encrypt
13
+ # @param [String] pwd the password to use when encrypting the file
14
+ def initialize(file_name, pwd)
15
+ self.password = pwd
16
+ self.file_name = file_name
17
+ end
18
+
19
+ # Generates a new CBF file based on this instance of ms-off-crypto and overwrites the unencrypted file.
20
+ def save
21
+ cfb = Cbf.new(self)
22
+ cfb.save
23
+ end
9
24
 
10
- def initialize(password = "passowrd")
11
- @password = password
12
- @salt_size = 0x10
13
- @key_size = 0x100
14
- @verifier = rand(16**16).to_s
25
+ # returns the raw password used in encryption
26
+ # @return [String]
27
+ attr_reader :password
15
28
 
16
- #fixed salt for testing
17
- @salt = [0x90,0xAC,0x68,0x0E,0x76,0xF9,0x43,0x2B,0x8D,0x13,0xB7,0x1D,0xB7,0xC0,0xFC,0x0D].join
18
- # @salt =Digest::SHA1.digest(rand(16**16).to_s)
29
+ # sets the password to be used for encryption
30
+ # @param [String] v the password, @default 'password'
31
+ # @return [String]
32
+ def password=(v)
33
+ @password = v || 'password'
19
34
  end
20
35
 
21
- def encryption_info
22
- # v.major v.minor flags header length flags size # AES 128 bit
23
- header = [3, 0, 2, 0, 0x24, 0, 0, 0, 0xA4, 0, 0, 0, 0x24, 0, 0, 0, 0, 0, 0, 0, 0x0E, 0x66, 0, 0]
24
- header.concat [0x04, 0x80, 0, 0, 0x80, 0, 0, 0, 0x18, 0, 0, 0, 0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
25
- header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a
26
- header.concat [0, 0]
27
- header.concat [0x10, 0, 0, 0]
28
- header.concat [0x90,0xAC,0x68,0x0E,0x76,0xF9,0x43,0x2B,0x8D,0x13,0xB7,0x1D,0xB7,0xC0,0xFC,0x0D]
29
- header.concat encrypted_verifier.bytes.to_a.pack('c*').bytes.to_a
30
- header.concat [20, 0,0,0]
31
- header.concat encrypted_verifier_hash.bytes.to_a.pack('c*').bytes.to_a
32
- header.flatten!
33
- header.pack('c*')
36
+ # retruns the file name of the archive to be encrypted
37
+ # @return [String]
38
+ attr_reader :file_name
39
+
40
+ # sets the filename
41
+ # @return [String]
42
+ def file_name=(v)
43
+ #TODO verfify that the file specified exists and is an unencrypted xlsx archive
44
+ @file_name = v
34
45
  end
35
46
 
36
- def encryption_verifier
37
- {:salt_size => @salt_size,
38
- :salt => @salt,
39
- :encrypted_verifier => encrypted_verifier,
40
- :varifier_hash_size => 0x14,
41
- :encrypted_verifier_hash => encrypted_verifier_hash}
47
+
48
+ # encrypts and returns the package specified by the file name
49
+ # @return [String]
50
+ def encrypted_package
51
+ @encrypted_package ||= encrypt_package(file_name, password)
42
52
  end
43
53
 
44
- # 2.3.3
54
+ # returns the encryption info for this instance of ms-off-crypto
55
+ # @return [String]
56
+ def encryption_info
57
+ @encryption_info ||= create_encryption_info
58
+ end
59
+
60
+ # returns a random salt
61
+ # @return [String]
62
+ def salt
63
+ @salt ||= Digest::SHA1.digest(rand(16**16).to_s)
64
+ end
65
+
66
+ # returns a random verifier
67
+ # @return [String]
68
+ def verifier
69
+ @verifier ||= rand(16**16).to_s
70
+ end
71
+
72
+ # returns the verifier encrytped
73
+ # @return [String]
45
74
  def encrypted_verifier
46
- @encrypted_verifier ||= encrypt(@verifier)
75
+ @encrypted_verifier ||= encrypt(verifier)
47
76
  end
48
77
 
49
- # 2.3.3
78
+ # returns the verifier hash encrypted
79
+ # @return [String]
50
80
  def encrypted_verifier_hash
51
- verifier_hash = Digest::SHA1.digest(@verifier)
52
- verifier_hash << Array.new(32 - verifier_hash.size, 0).join('')
53
81
  @encrypted_verifier_hash ||= encrypt(verifier_hash)
54
82
  end
55
83
 
84
+ # returns a verifier hash
85
+ # @return [String]
86
+ def verifier_hash
87
+ @verifier_hash ||= create_verifier_hash
88
+ end
89
+
90
+ # returns an encryption key
91
+ # @return [String]
92
+ def key
93
+ @key ||= create_key
94
+ end
95
+
96
+ # size of unencrypted package? concated with encrypted package
97
+ def encrypt_package(file_name, password)
98
+ package = File.open(file_name, 'r')
99
+ package_text = package.read
100
+ [package_text.bytes.to_a.size].pack('q') + encrypt(package_text)
101
+ end
102
+
103
+ # Generates an encryption info structure
104
+ # @return [String]
105
+ def create_encryption_info
106
+ header = [3, 0, 2, 0] # version
107
+ # Header flags copy
108
+ header.concat [0x24, 0, 0, 0] #flags -- VERY UNSURE ABOUT THIS STILL
109
+ header.concat [0, 0, 0, 0] #unused
110
+ header.concat [0xA4, 0, 0, 0] #length
111
+ # Header
112
+ header.concat [0x24, 0, 0, 0] #flags again
113
+ header.concat [0, 0, 0, 0] #unused again,
114
+ header.concat [0x0E, 0x66, 0, 0] #alg id
115
+ header.concat [0x04, 0x80, 0, 0] #alg hash id
116
+ header.concat [key.size, 0, 0, 0] #key size
117
+ header.concat [0x18, 0, 0, 0] #provider type
118
+ header.concat [0, 0, 0, 0] #reserved 1
119
+ header.concat [0, 0, 0, 0] #reserved 2
120
+ #header.concat [0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
121
+ header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a
122
+ header.concat [0, 0] #null terminator
123
+
124
+ #Salt Size
125
+ header.concat [salt.bytes.to_a.size].pack('l').bytes.to_a
126
+ #Salt
127
+ header.concat salt.bytes.to_a.pack('c*').bytes.to_a
128
+ # encryption verifier
129
+ header.concat encrypted_verifier.bytes.to_a.pack('c*').bytes.to_a
130
+
131
+ # verifier hash size -- MUST BE 32 bytes
132
+ header.concat [verifier_hash.bytes.to_a.size].pack('l').bytes.to_a
133
+
134
+ #encryption verifier hash
135
+ header.concat encrypted_verifier_hash.bytes.to_a.pack('c*').bytes.to_a
136
+
137
+ header.flatten!
138
+ header.pack('c*')
139
+ end
140
+
141
+ # 2.3.3
142
+ def create_verifier_hash
143
+ vh = Digest::SHA1.digest(verifier)
144
+ vh << Array.new(32 - vh.size, 0).join('')
145
+ end
146
+
56
147
  # 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)
57
- def key
58
- sha = Digest::SHA1.new() << (@salt + @password)
148
+ def create_key
149
+ sha = Digest::SHA1.new() << (salt + @password)
59
150
  (0..49999).each { |i| sha.update(i.to_s+sha.to_s) }
60
151
  key = sha.update(sha.to_s+'0').digest
61
152
  a = key.bytes.each_with_index.map { |item, i| 0x36 ^ item }
@@ -63,25 +154,35 @@ module Axlsx
63
154
  a = key.bytes.each_with_index.map { |item, i| 0x5C ^ item }
64
155
  x2 = Digest::SHA1.digest( (a.concat Array.new(64 - key.size, 0x5C) ).to_s)
65
156
  x3 = x1 + x2
66
- @key ||= x3.bytes.to_a[(0..31)].pack('c*')
157
+ x3.bytes.to_a[(0..31)].pack('c*')
67
158
  end
68
159
 
160
+ # ensures that the a hashed decryption of the encryption verifier matches the decrypted verifier hash.
161
+ # @return [Boolean]
69
162
  def verify_password
70
- puts decrypt(@encrypted_verifier)
163
+ v = Digest::SHA1.digest decrypt(@encrypted_verifier)
164
+ vh = decrypt(@encrypted_verifier_hash)
165
+ vh[0..15] == v[0..15]
71
166
  end
72
167
 
168
+ # encrypts the data proved
169
+ # @param [String] data
170
+ # @return [String] the encrypted data
73
171
  def encrypt(data)
74
172
  aes = OpenSSL::Cipher.new("AES-128-ECB")
75
173
  aes.encrypt
76
174
  aes.key = key
77
- aes.update(data)
175
+ aes.update(data) << aes.final
78
176
  end
79
177
 
178
+ # dencrypts the data proved
179
+ # @param [String] data
180
+ # @return [String] the dencrypted data
80
181
  def decrypt(data)
81
182
  aes = OpenSSL::Cipher.new("AES-128-ECB")
82
183
  aes.decrypt
83
184
  aes.key = key
84
- aes.update(data)
185
+ aes.update(data) << aes.final
85
186
  end
86
187
 
87
188
  end
@@ -132,14 +132,18 @@ module Axlsx
132
132
  # :drop_while
133
133
  # :delete_if
134
134
  # :clear
135
- def method_missing(meth, *args, &block)
136
- raise ArgumentError, "#{meth} not supported" if [:replace, :insert, :collect!, :map!, :pop, :delete_if, :reverse!, :shift, :shuffle!, :slice!, :sort!, :uniq!, :unshift, :zip, :flatten!, :fill, :drop, :drop_while, :delete_if, :clear].include? meth.to_sym
137
- if @list.respond_to? meth
138
- @list.send(meth, *args, &block)
139
- else
140
- puts "method:#{meth.inspect}"
141
- super
142
- end
135
+ DESTRUCTIVE = ['replace', 'insert', 'collect!', 'map!', 'pop', 'delete_if',
136
+ 'reverse!', 'shift', 'shuffle!', 'slice!', 'sort!', 'uniq!',
137
+ 'unshift', 'zip', 'flatten!', 'fill', 'drop', 'drop_while',
138
+ 'delete_if', 'clear']
139
+ DELEGATES = Array.instance_methods - self.instance_methods - DESTRUCTIVE
140
+
141
+ DELEGATES.each do |method|
142
+ class_eval %{
143
+ def #{method}(*args, &block)
144
+ @list.send(:#{method}, *args, &block)
145
+ end
146
+ }
143
147
  end
144
148
 
145
149
  # Serializes the list
@@ -0,0 +1,146 @@
1
+ module Axlsx
2
+
3
+ # The Storage class represents a storage object or stream in a compound file.
4
+ class Storage
5
+
6
+ # Packing for the Storage when pushing an array of items into a byte stream
7
+ # Name, name length, type, color, left sibling, right sibling, child, classid, state, created, modified, sector, size
8
+ PACKING = "s32 s1 c2 l3 x16 x4 q2 l q"
9
+
10
+ # storage types
11
+ TYPES = {
12
+ :root=>5,
13
+ :stream=>2,
14
+ :storage=>1
15
+ }
16
+
17
+ # Creates a byte string for this storage
18
+ # @return [String]
19
+ def to_s
20
+ data = [@name.concat(Array.new(32-@name.size, 0)),
21
+ @name_size,
22
+ @type,
23
+ @color,
24
+ @left,
25
+ @right,
26
+ @child,
27
+ @created,
28
+ @modified,
29
+ @sector,
30
+ @size].flatten
31
+ puts data.inspect
32
+ data.pack(PACKING)
33
+ end
34
+
35
+ # storage colors
36
+ COLORS = {
37
+ :red=>0,
38
+ :black=>1
39
+ }
40
+
41
+ # The color of this node in the directory tree. Defaults to black if not specified
42
+ # @return [Integer] color
43
+ attr_reader :color
44
+
45
+ # Sets the color for this storage
46
+ # @param [Integer] v Must be one of the COLORS constant hash values
47
+ def color=(v)
48
+ RestrictionValidator.validate "Storage.color", COLORS.values, v
49
+ @color = v
50
+ end
51
+
52
+ # The size of the name for this node.
53
+ # interesting to see that office actually uses 'R' for the root directory and lists the size as 2 bytes - thus is it *NOT* null
54
+ # terminated. I am making this r/w so that I can override the size
55
+ # @return [Integer] color
56
+ attr_reader :name_size
57
+
58
+ # the name of the stream
59
+ attr_reader :name
60
+
61
+ # sets the name of the stream.
62
+ # This will automatically set the name_size attribute
63
+ # @return [String] name
64
+ def name=(v)
65
+ @name = v.bytes.to_a << 0
66
+ @name_size = @name.size * 2
67
+ @name
68
+ end
69
+
70
+ # The size of the stream
71
+ attr_reader :size
72
+
73
+ # The stream associated with this storage
74
+ attr_reader :data
75
+
76
+ # Set the data associated with the stream. If the stream type is undefined, we automatically specify the storage as a stream type. # with the exception of storages that are type root, all storages with data should be type stream.
77
+ # @param [String] v The data for this storages stream
78
+ # @return [Array]
79
+ def data=(v)
80
+ Axlsx::validate_string(v)
81
+ self.type = TYPES[:stream] unless @type
82
+ @size = v.size
83
+ @data = v.bytes.to_a
84
+ end
85
+
86
+ # The starting sector for the stream. If this storage is not a stream, or the root node this is nil
87
+ # @return [Integer] sector
88
+ attr_accessor :sector
89
+
90
+ # The 0 based index in the directoies chain for this the left sibling of this storage.
91
+
92
+ # @return [Integer] left
93
+ attr_accessor :left
94
+
95
+ # The 0 based index in the directoies chain for this the right sibling of this storage.
96
+ # @return [Integer] right
97
+ attr_accessor :right
98
+
99
+ # The 0 based index in the directoies chain for the child of this storage.
100
+ # @return [Integer] child
101
+ attr_accessor :child
102
+
103
+ # The created attribute for the storage
104
+ # @return [Integer] created
105
+ attr_accessor :created
106
+
107
+ # The modified attribute for the storage
108
+ # @return [Integer] modified
109
+ attr_accessor :modified
110
+
111
+ # The type of storage
112
+ # see TYPES
113
+ # @return [Integer] type
114
+ attr_reader :type
115
+
116
+ # Sets the type for this storage.
117
+ # @param [Integer] v the type to specify must be one of the TYPES constant hash values.
118
+ def type=(v)
119
+ RestrictionValidator.validate "Storage.type", TYPES.values, v
120
+ @type = v
121
+ end
122
+
123
+ # Creates a new storage object.
124
+ # @param [String] name the name of the storage
125
+ # @option options [Integer] color @default black
126
+ # @option options [Integer] type @default storage
127
+ # @option options [String] data
128
+ # @option options [Integer] left @default -1
129
+ # @option options [Integer] right @default -1
130
+ # @option options [Integer] child @default -1
131
+ # @option options [Integer] created @default 0
132
+ # @option options [Integer] modified @default 0
133
+ # @option options [Integer] sector @default 0
134
+ def initialize(name, options= {})
135
+ @left = @right = @child = -1
136
+ @sector = @size = @created = @modified = 0
137
+ options.each do |o|
138
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
139
+ end
140
+ @color ||= COLORS[:black]
141
+ @type ||= (data.nil? ? TYPES[:storage] : TYPES[:stream])
142
+ self.name = name
143
+ end
144
+
145
+ end
146
+ end
@@ -1,4 +1,7 @@
1
1
  module Axlsx
2
2
  # version
3
- VERSION="1.0.14"
3
+ # When using bunle exec rake and referencing the gem on github or locally
4
+ # it will use the gemspec, which preloads this constant for the gem's version.
5
+ # We check to make sure that it has not already been loaded
6
+ VERSION="1.0.15" unless Axlsx.const_defined? :VERSION
4
7
  end
@@ -48,7 +48,7 @@ module Axlsx
48
48
  def type=(v)
49
49
  RestrictionValidator.validate "Cell.type", [:time, :float, :integer, :string], v
50
50
  @type=v
51
- self.value = @value
51
+ self.value = @value unless @value.nil?
52
52
  end
53
53
 
54
54
 
@@ -175,14 +175,14 @@ module Axlsx
175
175
  # @option options [String] color an 8 letter rgb specification
176
176
  # @option options [Symbol] scheme must be one of :none, major, :minor
177
177
  def initialize(row, value="", options={})
178
- self.row=row
178
+ self.row=row
179
179
  @styles = row.worksheet.workbook.styles
180
- @style = 0
181
- @type = cell_type_from_value(value)
182
180
  @row.cells << self
183
181
  options.each do |o|
184
182
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
185
183
  end
184
+ @style ||= 0
185
+ @type ||= cell_type_from_value(value)
186
186
  @value = cast_value(value)
187
187
  end
188
188
 
metadata CHANGED
@@ -1,168 +1,128 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: axlsx
3
- version: !ruby/object:Gem::Version
4
- hash: 11
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.15
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 0
9
- - 14
10
- version: 1.0.14
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Randy Morgan
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-12-14 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
12
+ date: 2012-01-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &2155999180 !ruby/object:Gem::Requirement
22
17
  none: false
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- hash: 5
27
- segments:
28
- - 1
29
- - 4
30
- - 1
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
31
21
  version: 1.4.1
32
- requirement: *id001
33
22
  type: :runtime
34
23
  prerelease: false
35
- name: nokogiri
36
- - !ruby/object:Gem::Dependency
37
- version_requirements: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2155999180
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &2155993560 !ruby/object:Gem::Requirement
38
28
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 17
43
- segments:
44
- - 2
45
- - 3
46
- - 9
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
47
32
  version: 2.3.9
48
- requirement: *id002
49
33
  type: :runtime
50
34
  prerelease: false
51
- name: activesupport
52
- - !ruby/object:Gem::Dependency
53
- version_requirements: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2155993560
36
+ - !ruby/object:Gem::Dependency
37
+ name: i18n
38
+ requirement: &2153146240 !ruby/object:Gem::Requirement
54
39
  none: false
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 7
59
- segments:
60
- - 0
61
- - 6
62
- - 0
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
63
43
  version: 0.6.0
64
- requirement: *id003
65
44
  type: :runtime
66
45
  prerelease: false
67
- name: i18n
68
- - !ruby/object:Gem::Dependency
69
- version_requirements: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2153146240
47
+ - !ruby/object:Gem::Dependency
48
+ name: rmagick
49
+ requirement: &2153145780 !ruby/object:Gem::Requirement
70
50
  none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- hash: 59
75
- segments:
76
- - 2
77
- - 12
78
- - 2
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
79
54
  version: 2.12.2
80
- requirement: *id004
81
55
  type: :runtime
82
56
  prerelease: false
83
- name: rmagick
84
- - !ruby/object:Gem::Dependency
85
- version_requirements: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *2153145780
58
+ - !ruby/object:Gem::Dependency
59
+ name: rubyzip
60
+ requirement: &2153145320 !ruby/object:Gem::Requirement
86
61
  none: false
87
- requirements:
62
+ requirements:
88
63
  - - ~>
89
- - !ruby/object:Gem::Version
90
- hash: 25
91
- segments:
92
- - 0
93
- - 9
94
- version: "0.9"
95
- requirement: *id005
64
+ - !ruby/object:Gem::Version
65
+ version: '0.9'
96
66
  type: :runtime
97
67
  prerelease: false
98
- name: rubyzip
99
- - !ruby/object:Gem::Dependency
100
- version_requirements: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *2153145320
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &2153144780 !ruby/object:Gem::Requirement
101
72
  none: false
102
- requirements:
73
+ requirements:
103
74
  - - ~>
104
- - !ruby/object:Gem::Version
105
- hash: 25
106
- segments:
107
- - 0
108
- - 9
109
- version: "0.9"
110
- requirement: *id006
75
+ - !ruby/object:Gem::Version
76
+ version: '0.9'
111
77
  type: :development
112
78
  prerelease: false
113
- name: rake
114
- - !ruby/object:Gem::Dependency
115
- version_requirements: &id007 !ruby/object:Gem::Requirement
79
+ version_requirements: *2153144780
80
+ - !ruby/object:Gem::Dependency
81
+ name: yard
82
+ requirement: &2153144400 !ruby/object:Gem::Requirement
116
83
  none: false
117
- requirements:
118
- - - ">="
119
- - !ruby/object:Gem::Version
120
- hash: 3
121
- segments:
122
- - 0
123
- version: "0"
124
- requirement: *id007
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
125
88
  type: :development
126
89
  prerelease: false
90
+ version_requirements: *2153144400
91
+ - !ruby/object:Gem::Dependency
127
92
  name: yard
128
- - !ruby/object:Gem::Dependency
129
- version_requirements: &id008 !ruby/object:Gem::Requirement
93
+ requirement: &2153143940 !ruby/object:Gem::Requirement
130
94
  none: false
131
- requirements:
132
- - - ">="
133
- - !ruby/object:Gem::Version
134
- hash: 3
135
- segments:
136
- - 0
137
- version: "0"
138
- requirement: *id008
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
139
99
  type: :development
140
100
  prerelease: false
141
- name: yard
142
- - !ruby/object:Gem::Dependency
143
- version_requirements: &id009 !ruby/object:Gem::Requirement
101
+ version_requirements: *2153143940
102
+ - !ruby/object:Gem::Dependency
103
+ name: rdiscount
104
+ requirement: &2153143520 !ruby/object:Gem::Requirement
144
105
  none: false
145
- requirements:
146
- - - ">="
147
- - !ruby/object:Gem::Version
148
- hash: 3
149
- segments:
150
- - 0
151
- version: "0"
152
- requirement: *id009
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
153
110
  type: :development
154
111
  prerelease: false
155
- name: rdiscount
156
- description: " xlsx generation with charts, images, automated column width, customizable styles and full schema validation. Axlsx excels at helping you generate beautiful Office Open XML Spreadsheet documents without having to understand the entire ECMA specification. Check out the README for some examples of how easy it is. Best of all, you can validate your xlsx file before serialization so you know for sure that anything generated is going to load on your client's machine.\n"
112
+ version_requirements: *2153143520
113
+ description: ! ' xlsx generation with charts, images, automated column width, customizable
114
+ styles and full schema validation. Axlsx excels at helping you generate beautiful
115
+ Office Open XML Spreadsheet documents without having to understand the entire ECMA
116
+ specification. Check out the README for some examples of how easy it is. Best of
117
+ all, you can validate your xlsx file before serialization so you know for sure that
118
+ anything generated is going to load on your client''s machine.
119
+
120
+ '
157
121
  email: digital.ipseity@gmail.com
158
122
  executables: []
159
-
160
123
  extensions: []
161
-
162
124
  extra_rdoc_files: []
163
-
164
- files:
165
- - lib/axlsx/#cfb.xlsx#
125
+ files:
166
126
  - lib/axlsx/content_type/content_type.rb
167
127
  - lib/axlsx/content_type/default.rb
168
128
  - lib/axlsx/content_type/override.rb
@@ -214,6 +174,8 @@ files:
214
174
  - lib/axlsx/stylesheet/table_style_element.rb
215
175
  - lib/axlsx/stylesheet/table_styles.rb
216
176
  - lib/axlsx/stylesheet/xf.rb
177
+ - lib/axlsx/util/cbf.rb
178
+ - lib/axlsx/util/cfb.rb~
217
179
  - lib/axlsx/util/constants.rb
218
180
  - lib/axlsx/util/ms_off_crypto.rb
219
181
  - lib/axlsx/util/ms_off_crypto.rb~
@@ -221,6 +183,8 @@ files:
221
183
  - lib/axlsx/util/parser.rb
222
184
  - lib/axlsx/util/parser.rb~
223
185
  - lib/axlsx/util/simple_typed_list.rb
186
+ - lib/axlsx/util/storage.rb
187
+ - lib/axlsx/util/storage.rb~
224
188
  - lib/axlsx/util/validators.rb
225
189
  - lib/axlsx/version.rb
226
190
  - lib/axlsx/workbook/workbook.rb
@@ -337,40 +301,29 @@ files:
337
301
  - test/workbook/worksheet/tc_worksheet.rb
338
302
  homepage: https://github.com/randym/axlsx
339
303
  licenses: []
340
-
341
304
  post_install_message:
342
305
  rdoc_options: []
343
-
344
- require_paths:
306
+ require_paths:
345
307
  - lib
346
- required_ruby_version: !ruby/object:Gem::Requirement
308
+ required_ruby_version: !ruby/object:Gem::Requirement
347
309
  none: false
348
- requirements:
349
- - - ">="
350
- - !ruby/object:Gem::Version
351
- hash: 57
352
- segments:
353
- - 1
354
- - 8
355
- - 7
310
+ requirements:
311
+ - - ! '>='
312
+ - !ruby/object:Gem::Version
356
313
  version: 1.8.7
357
- required_rubygems_version: !ruby/object:Gem::Requirement
314
+ required_rubygems_version: !ruby/object:Gem::Requirement
358
315
  none: false
359
- requirements:
360
- - - ">="
361
- - !ruby/object:Gem::Version
362
- hash: 3
363
- segments:
364
- - 0
365
- version: "0"
316
+ requirements:
317
+ - - ! '>='
318
+ - !ruby/object:Gem::Version
319
+ version: '0'
366
320
  requirements: []
367
-
368
321
  rubyforge_project:
369
322
  rubygems_version: 1.8.10
370
323
  signing_key:
371
324
  specification_version: 3
372
325
  summary: excel OOXML (xlsx) with charts, styles, images and autowidth columns.
373
- test_files:
326
+ test_files:
374
327
  - test/content_type/tc_content_type.rb
375
328
  - test/content_type/tc_default.rb
376
329
  - test/content_type/tc_override.rb