xmlss 1.0.0.rc.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -2
- data/Gemfile +4 -5
- data/LICENSE.txt +22 -0
- data/{README.rdoc → README.md} +74 -71
- data/Rakefile +1 -7
- data/lib/xmlss/element/cell.rb +5 -0
- data/lib/xmlss/element/worksheet.rb +1 -0
- data/lib/xmlss/version.rb +1 -1
- data/lib/xmlss/writer.rb +53 -60
- data/test/helper.rb +6 -3
- data/test/unit/element/cell_tests.rb +124 -0
- data/test/{element/column_test.rb → unit/element/column_tests.rb} +14 -12
- data/test/{element/row_test.rb → unit/element/row_tests.rb} +14 -13
- data/test/{element/worksheet_test.rb → unit/element/worksheet_tests.rb} +16 -11
- data/test/{element_stack_test.rb → unit/element_stack_tests.rb} +5 -13
- data/test/{style/alignment_test.rb → unit/style/alignment_tests.rb} +17 -16
- data/test/{style/base_test.rb → unit/style/base_tests.rb} +7 -7
- data/test/{style/border_test.rb → unit/style/border_tests.rb} +18 -24
- data/test/{style/font_test.rb → unit/style/font_tests.rb} +8 -7
- data/test/{style/interior_test.rb → unit/style/interior_tests.rb} +6 -6
- data/test/{style/number_format_test.rb → unit/style/number_format_tests.rb} +6 -5
- data/test/{style/protection_test.rb → unit/style/protection_tests.rb} +2 -3
- data/test/{workbook_test.rb → unit/workbook_tests.rb} +2 -2
- data/test/{writer_test.rb → unit/writer_tests.rb} +20 -32
- data/xmlss.gemspec +20 -18
- metadata +58 -85
- data/Gemfile.lock +0 -33
- data/test/element/cell_test.rb +0 -117
- data/test/irb.rb +0 -10
- data/test/thing.rb +0 -9
data/.gitignore
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
-
pkg/*
|
2
|
-
.bundle
|
3
1
|
*.gem
|
4
2
|
*.log
|
3
|
+
*.rbc
|
4
|
+
.rbx/
|
5
|
+
.bundle
|
6
|
+
.config
|
7
|
+
.yardoc
|
8
|
+
Gemfile.lock
|
9
|
+
InstalledFiles
|
10
|
+
_yardoc
|
11
|
+
coverage
|
12
|
+
doc/
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
20
|
+
|
5
21
|
bench/*.xml
|
data/Gemfile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
source "
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in xmlss.gemspec
|
4
3
|
gemspec
|
5
4
|
|
6
|
-
gem '
|
7
|
-
gem '
|
8
|
-
gem "whysoslow"
|
5
|
+
gem 'rake'
|
6
|
+
gem 'pry'
|
7
|
+
gem "whysoslow"
|
9
8
|
gem 'ruby-prof'
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2011-Present Kelly Redding
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,37 +1,35 @@
|
|
1
|
-
|
1
|
+
# Xmlss
|
2
2
|
A ruby DSL for generating spreadsheets in the XML Spreadsheet format. It provides an api for constructing spreadsheet data and then uses that data to generate xml that can be interpreted by MS Excel.
|
3
3
|
|
4
4
|
** Note: this gem only generates XML according to a subset of the August 2001 XML Spreadsheet spec (http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx). It does not generate the more modern open office spreadsheet spec (xlsx) and may have limited support in modern spreadsheet applications.
|
5
5
|
|
6
|
-
|
6
|
+
## Simple Usage Example
|
7
7
|
|
8
|
-
|
8
|
+
```ruby
|
9
|
+
require 'xmlss'
|
9
10
|
|
10
|
-
|
11
|
+
workbook = Xmlss::Workbook.new(Xmlss::Writer.new) do
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
worksheet("5 columns, 1 row") {
|
17
|
-
5.times do
|
18
|
-
column
|
19
|
-
end
|
13
|
+
worksheet("5 columns, 1 row") {
|
14
|
+
5.times do
|
15
|
+
column
|
16
|
+
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
}
|
18
|
+
row {
|
19
|
+
# put data into the row (infer type)
|
20
|
+
[1, "text", 123.45, "0001267", "$45.23"].each do |data_value|
|
21
|
+
cell { data data_value }
|
27
22
|
end
|
28
23
|
}
|
29
|
-
|
30
24
|
end
|
25
|
+
}
|
31
26
|
|
32
|
-
|
27
|
+
end
|
33
28
|
|
34
|
-
|
29
|
+
workbook.to_s # => "..." (XML Spreadsheet xml string)
|
30
|
+
```
|
31
|
+
|
32
|
+
## DSL / API
|
35
33
|
|
36
34
|
Use these directives to create workbook markup elements.
|
37
35
|
|
@@ -104,57 +102,65 @@ number_format(value):
|
|
104
102
|
protection(value):
|
105
103
|
* value: bool, default: false
|
106
104
|
|
107
|
-
|
105
|
+
## Usage
|
108
106
|
|
109
107
|
To generate a spreadsheet, create an Xmlss::Workbook instance and build the workbook using the above DSL. Workbook takes three parameters:
|
110
108
|
* Xmlss::Writer instance
|
111
109
|
* data hash: (optional) key value data to bind to the workbook scope
|
112
110
|
* build block: (optional) block containing DSL directives
|
113
111
|
|
114
|
-
|
112
|
+
### Writer (Undies)
|
115
113
|
|
116
114
|
The Xmlss::Writer uses Undies (https://github.com/kellyredding/undies) to write the XML output. The writer takes Undies::IO options. See the Undies README for usage details.
|
117
115
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
116
|
+
```ruby
|
117
|
+
Xmlss::Workbook.new(Xmlss::Writer.new(:pp => 2)) do
|
118
|
+
worksheet('A cool sheet') {
|
119
|
+
...
|
120
|
+
}
|
121
|
+
end
|
122
|
+
```
|
123
123
|
|
124
|
-
|
124
|
+
### Data hash
|
125
125
|
|
126
126
|
Xmlss evals the build proc in the scope of the workbook instance. This means that the build has access to only the data it is given or the DSL itself. Data is given in the form of a Hash. The string form of the hash keys are exposed as local workbook methods that return their corresponding values.
|
127
127
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
128
|
+
```ruby
|
129
|
+
Xmlss::Workbook.new(Xmlss::Writer.new, :sheet_name => 'A cool sheet') do
|
130
|
+
worksheet(sheet_name) {
|
131
|
+
...
|
132
|
+
}
|
133
|
+
end
|
134
|
+
```
|
133
135
|
|
134
|
-
|
136
|
+
### Builder approach
|
135
137
|
|
136
138
|
The above examples all pass in a build proc that is eval'd in the scope of the workbook instance. This works great when you know your build at the same time you create your Workbook object. However, in some cases, the build may not be known upfront or you may want to use a more declarative style to specify your spreadsheet content. Workbook builds can be specified programmatically using the "builder" approach.
|
137
139
|
|
138
140
|
To render using this approach, create a Workbook instance passing it data and output info as above. However, don't pass any build proc and save off the created workbook:
|
139
141
|
|
140
|
-
|
141
|
-
|
142
|
+
```ruby
|
143
|
+
# choosing not to use any local data or output options
|
144
|
+
workbook = Xmlss::Workbook.new(Xmlss::Writer.new)
|
145
|
+
```
|
142
146
|
|
143
147
|
Now just interact with the Workbook API directly.
|
144
148
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
+
```ruby
|
150
|
+
# notice that it becomes less important to bind any local data to the Workbook using this approach
|
151
|
+
something = "Some Thing!"
|
152
|
+
workbook.worksheet(something) {
|
153
|
+
workbook.column
|
149
154
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
}
|
154
|
-
}
|
155
|
+
workbook.row {
|
156
|
+
workbook.cell {
|
157
|
+
workbook.data "hi hi something hi"
|
155
158
|
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
```
|
156
162
|
|
157
|
-
|
163
|
+
# Disclaimer
|
158
164
|
|
159
165
|
Be aware this library only provides the basic, raw API for constructing spreadsheets using this spec and utilities to convert those objects to string xml data representing them. It does not provide any macro logic to aid in constructing the sheets. If you want a more convenient API for your use case, I suggest extending the objects and tailoring them to your needs.
|
160
166
|
|
@@ -164,27 +170,24 @@ The XML Spreadsheet spec and format are legacy and may have limited support depe
|
|
164
170
|
|
165
171
|
* Full XML Spreadsheet spec: http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx
|
166
172
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
189
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
190
|
-
OTHER DEALINGS IN THE SOFTWARE.
|
173
|
+
## Installation
|
174
|
+
|
175
|
+
Add this line to your application's Gemfile:
|
176
|
+
|
177
|
+
gem 'whysoslow'
|
178
|
+
|
179
|
+
And then execute:
|
180
|
+
|
181
|
+
$ bundle
|
182
|
+
|
183
|
+
Or install it yourself as:
|
184
|
+
|
185
|
+
$ gem install whysoslow
|
186
|
+
|
187
|
+
## Contributing
|
188
|
+
|
189
|
+
1. Fork it
|
190
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
191
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
192
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
193
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
data/lib/xmlss/element/cell.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'enumeration'
|
2
|
+
require 'date'
|
2
3
|
|
3
4
|
module Xmlss; end
|
4
5
|
module Xmlss::Element
|
@@ -38,6 +39,10 @@ module Xmlss::Element
|
|
38
39
|
case self.data
|
39
40
|
when ::Date, ::Time, ::DateTime
|
40
41
|
self.data.strftime("%Y-%m-%dT%H:%M:%S")
|
42
|
+
when ::TrueClass
|
43
|
+
1
|
44
|
+
when ::FalseClass
|
45
|
+
0
|
41
46
|
else
|
42
47
|
self.data.to_s
|
43
48
|
end
|
data/lib/xmlss/version.rb
CHANGED
data/lib/xmlss/writer.rb
CHANGED
@@ -4,9 +4,6 @@ require 'stringio'
|
|
4
4
|
module Xmlss
|
5
5
|
class Writer
|
6
6
|
|
7
|
-
class Markup; end
|
8
|
-
class AttrsHash; end
|
9
|
-
|
10
7
|
# Xmlss uses Undies to stream its xml markup
|
11
8
|
# The Undies writer is responsible for driving the Undies API to generate
|
12
9
|
# the xmlss xml markup for the workbook.
|
@@ -192,79 +189,75 @@ module Xmlss
|
|
192
189
|
worksheets_markup.element("Table", nil, {})
|
193
190
|
end
|
194
191
|
|
195
|
-
|
196
|
-
|
197
|
-
|
192
|
+
# utility classes
|
198
193
|
|
199
|
-
|
194
|
+
class AttrsHash
|
195
|
+
attr_reader :raw
|
200
196
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
@raw = Hash.new
|
205
|
-
end
|
197
|
+
def initialize
|
198
|
+
@raw = Hash.new
|
199
|
+
end
|
206
200
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
201
|
+
def value(k, v)
|
202
|
+
# ignore any nil-value or empty string attrs
|
203
|
+
@raw["#{Xmlss::Writer::SHEET_NS}:#{k}"] = v if v && v != ''
|
204
|
+
self
|
205
|
+
end
|
212
206
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
207
|
+
def bool(k, v)
|
208
|
+
# write truthy values as '1', otherwise ignore
|
209
|
+
@raw["#{Xmlss::Writer::SHEET_NS}:#{k}"] = 1 if v
|
210
|
+
self
|
211
|
+
end
|
217
212
|
end
|
218
213
|
|
219
|
-
|
220
|
-
|
221
|
-
class Writer::Markup
|
214
|
+
class Markup
|
215
|
+
attr_reader :template, :push_count, :pop_count
|
222
216
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
@pop_count = 0
|
230
|
-
end
|
217
|
+
def initialize(opts={})
|
218
|
+
@markup = ""
|
219
|
+
@template = Undies::Template.new(Undies::IO.new(@markup, opts))
|
220
|
+
@push_count = 0
|
221
|
+
@pop_count = 0
|
222
|
+
end
|
231
223
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
224
|
+
def raw(markup)
|
225
|
+
@template.raw(
|
226
|
+
Undies::Template.escape_html(markup).gsub(/(\r|\n)+/, Xmlss::Writer::LB)
|
227
|
+
)
|
228
|
+
end
|
237
229
|
|
238
|
-
|
239
|
-
|
240
|
-
|
230
|
+
def element(name, data, attrs)
|
231
|
+
@template.__open_element(name, data, attrs)
|
232
|
+
end
|
241
233
|
|
242
|
-
|
243
|
-
|
244
|
-
|
234
|
+
def inline_element(name, attrs)
|
235
|
+
@template.__closed_element(name, attrs)
|
236
|
+
end
|
245
237
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
238
|
+
def push
|
239
|
+
@push_count += 1
|
240
|
+
@template.__push
|
241
|
+
end
|
250
242
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
243
|
+
def pop
|
244
|
+
@pop_count += 1
|
245
|
+
@template.__pop
|
246
|
+
end
|
255
247
|
|
256
|
-
|
257
|
-
|
258
|
-
|
248
|
+
def flush
|
249
|
+
while @push_count > @pop_count
|
250
|
+
pop
|
251
|
+
end
|
252
|
+
@template.__flush
|
253
|
+
self
|
259
254
|
end
|
260
|
-
@template.__flush
|
261
|
-
self
|
262
|
-
end
|
263
255
|
|
264
|
-
|
256
|
+
def empty?; @markup.empty?; end
|
265
257
|
|
266
|
-
|
267
|
-
|
258
|
+
def to_s
|
259
|
+
@markup.to_s
|
260
|
+
end
|
268
261
|
end
|
269
262
|
|
270
263
|
end
|
data/test/helper.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
# this file is automatically required
|
2
|
-
# put test helpers here
|
1
|
+
# this file is automatically required when you run `assert`
|
2
|
+
# put any test helpers here
|
3
3
|
|
4
|
-
# add root dir to the load path
|
4
|
+
# add the root dir to the load path
|
5
5
|
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
6
6
|
|
7
|
+
# require pry for debugging (`binding.pry`)
|
8
|
+
require 'pry'
|
9
|
+
|
7
10
|
class Assert::Context
|
8
11
|
|
9
12
|
def self.be_styled
|