rodf 1.1.1 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 448589026c98db61c56b1f4078725adf5cb08282a9257cc0be55ba6f6d90d885
4
- data.tar.gz: 2c387630e0250037207433aad4fc886a7e5cbddf624fb1b1943d0aae6585fd7d
3
+ metadata.gz: 97ad9b10231e7a1a3b553c83880873a7543cfad68b622c8a5884c177f997d208
4
+ data.tar.gz: 968d57b5f72cfe03350cd7a2f929224b34e857c41758d7b30cd7a4ae47367661
5
5
  SHA512:
6
- metadata.gz: 974dc5d9c321154811ed47ce27f1c04d065542c08242bbc0f65f9c3c3e685cd80b3165b9ddc0f10eebfc13643cbb38aef48dd92da83dc367990afac78f46d783
7
- data.tar.gz: ad463dcab3b3589b4e29fc50b224323a05a23cc662923bf73bcc02b49105daee0de0ee72cbe29c0843a12df6ecef7d25742c295aaee3f8dc8f54544961ad8e08
6
+ metadata.gz: d44ab7bb0070d832969272e6b0f9350792a346e192a703d4c23708aecbdbf4347ad01eb0fc2a546407712394795d40f983c6162c078c084215cf1707a617f887
7
+ data.tar.gz: 13bdfa011468af90e8c475a1f02aa30a7f8c29b6e0a1c12f4849d15da0eb2d42a65eb9b853f9891ac4501901c25f7df8b9c2be6867bcba5c50d7abd40c688b6a
data/CHANGELOG.md CHANGED
@@ -1,20 +1,28 @@
1
1
  # CHANGELOG
2
2
 
3
- ## Unreleased
3
+ ## Unreleased - [View Diff](https://github.com/westonganger/rodf/compare/v1.2.0..master)
4
4
  - Nothing yet
5
5
 
6
- ## v1.1.1
6
+ ## v1.2.0 - [View Diff](https://github.com/westonganger/rodf/compare/v1.1.1..v1.2.0)
7
+ - Allow passing `:style` argument to `Span`
8
+ - Added `Table#set_column_widths` method
9
+ - Style `:family` option now supports String and Symbol keys. Previously `:family` the family option would only support the key name as a Symbol.
10
+ - Improve Style List Documentation
11
+ - Allow adding XML attributes directly to `Table`, `Row`, `Column`, `Cell` using the `:attributes` argument
12
+ - Remove usage of `contains` metaprogramming method `Container#contains` that was hiding major implementation details from most RODF classes. The code is now much easier to understand.
13
+
14
+ ## v1.1.1 - [View Diff](https://github.com/westonganger/rodf/compare/v1.1.0..v1.1.1)
7
15
  - [Issue #36](https://github.com/westonganger/rodf/issues/36) - Improve compatibility for Float Cells
8
16
  - Fix gemspec require for Ruby 1.9
9
17
  - Cleanup File Commenting
10
18
 
11
- ## v1.1.0
19
+ ## v1.1.0 - [View Diff](https://github.com/westonganger/rodf/compare/v1.0.0..v1.1.0)
12
20
  - [#34](https://github.com/westonganger/rodf/pull/34) - Add ability to add many rows or cells at once
13
21
  - [#29](https://github.com/westonganger/rodf/pull/29) - Remove ActiveSupport dependency in favor of `dry-inflector`
14
22
  - [#21](https://github.com/thiagoarrais/rodf/pull/21) - Allow more attributes for the `data_style` method
15
23
  - [#19](https://github.com/westonganger/rodf/issues/19) - Changes to Date/Time handling
16
24
 
17
- ## v1.0.0
25
+ ## v1.0.0 - [View Diff](https://github.com/westonganger/rodf/compare/v0.3.7..v1.0.0)
18
26
  - Rename main module ODF to RODF, Fix cell types
19
27
 
20
28
  ## v0.3.7
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # RODF
2
2
  <a href="https://badge.fury.io/rb/rodf" target="_blank"><img height="21" style='border:0px;height:21px;' border='0' src="https://badge.fury.io/rb/rodf.svg" alt="Gem Version"></a>
3
- <a href='https://travis-ci.com/westonganger/rodf' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://travis-ci.com/westonganger/rodf.svg?branch=master' border='0' alt='Build Status' /></a>
3
+ <a href='https://github.com/westonganger/rodf/actions' target='_blank'><img src="https://github.com/westonganger/rodf/workflows/Tests/badge.svg" style="max-width:100%;" height='21' style='border:0px;height:21px;' border='0' alt="CI Status"></a>
4
4
  <a href='https://rubygems.org/gems/rodf' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://ruby-gem-downloads-badge.herokuapp.com/rodf?label=rubygems&type=total&total_label=downloads&color=brightgreen' border='0' alt='RubyGems Downloads' /></a>
5
5
  <a href='https://ko-fi.com/A5071NK' target='_blank'><img height='22' style='border:0px;height:22px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
6
6
 
@@ -14,13 +14,11 @@ As well as writing ODS spreadsheets, this library also can write ODT text docume
14
14
  gem install rodf
15
15
  ```
16
16
 
17
- ## How do I use it?
17
+ ## Usage
18
18
 
19
19
  RODF works pretty much like Builder, but with ODF-aware constructs. For example:
20
20
 
21
21
  ```ruby
22
- require 'rodf'
23
-
24
22
  RODF::Spreadsheet.file("my-spreadsheet.ods") do
25
23
  table 'My first table from Ruby' do
26
24
  row do
@@ -33,12 +31,10 @@ end
33
31
  For access to variables and methods from outer code you can use block parameter:
34
32
 
35
33
  ```ruby
36
- require 'rodf'
37
-
38
34
  @data = 'Hello world!'
39
35
 
40
- RODF::Spreadsheet.file("my-spreadsheet.ods") do |spreadsheet|
41
- spreadsheet.table 'My first table from Ruby' do |table|
36
+ RODF::Spreadsheet.file("my-spreadsheet.ods") do |sheet|
37
+ sheet.table 'My first table from Ruby' do |table|
42
38
  table.row do |row|
43
39
  row.cell @data
44
40
  end
@@ -49,18 +45,16 @@ end
49
45
  Adding many rows or cells at once is supported as well:
50
46
 
51
47
  ```ruby
52
- require 'rodf'
53
-
54
- RODF::Spreadsheet.file("my-spreadsheet.ods") do
55
- table 'My first table from Ruby' do
56
- add_rows([
48
+ RODF::Spreadsheet.file("my-spreadsheet.ods") do |sheet|
49
+ sheet.table 'My first table from Ruby' do |t|
50
+ t.add_rows([
57
51
  [1, 'Alice'],
58
52
  [2, { value: 'Bob', color: '#ff0000'}],
59
53
  [3, 'Carol']
60
54
  ])
61
55
 
62
- row do
63
- add_cells ['ID', 'Name']
56
+ t.row do |r|
57
+ r.add_cells ['ID', 'Name']
64
58
  end
65
59
  end
66
60
  end
@@ -71,9 +65,8 @@ end
71
65
  The declarative style shown above is just syntatic sugar. A more procedural style can also be used. Like so:
72
66
 
73
67
  ```ruby
74
- require 'rodf'
75
-
76
68
  ss = RODF::Spreadsheet.new
69
+
77
70
  t = ss.table 'My first table from Ruby'
78
71
  r = t.row
79
72
  c = r.cell 'Hello world!'
@@ -82,82 +75,130 @@ c = r.cell 'Hello world!'
82
75
  ss.write_to 'my-spreadsheet.ods'
83
76
  # or
84
77
  File.write('my-spreadsheet.ods', ss.bytes) # you can send your data in Rails over HTTP using the bytes method
85
- end
86
78
  ```
87
79
 
88
80
  Both styles can be mixed and matched at will:
89
81
 
90
82
  ```ruby
91
- require 'rodf'
92
-
93
83
  ss = RODF::Spreadsheet.new
94
- ss.table 'My first table from Ruby' do
95
- row do
96
- cell 'Hello world!'
84
+
85
+ ss.table 'My first table from Ruby' do |t|
86
+ t.row do |r|
87
+ r.cell 'Hello world!'
97
88
  end
98
89
  end
99
90
 
100
91
  ss.write_to 'my-spreadsheet.ods'
101
92
  ```
102
93
 
103
- Styling and formatting is also possible:
94
+ ## Styling and Formatting
104
95
 
105
96
  ```ruby
106
- require 'rodf'
97
+ RODF::Spreadsheet.file("my-spreadsheet.ods") do |sheet|
107
98
 
108
- RODF::Spreadsheet.file("my-spreadsheet.ods") do
109
- style 'red-cell', family: :cell do
110
- property :text, 'font-weight' => 'bold', 'color' => '#ff0000'
99
+ sheet.style 'red-cell', family: :cell do |s|
100
+ s.property :text, 'font-weight' => 'bold', 'color' => '#ff0000'
111
101
  end
112
102
 
113
- table 'Red text table' do
114
- row do
115
- cell 'Red', style: 'red-cell'
103
+ sheet.style 'row-height', family: :row do |s|
104
+ s.property :row, 'row-height' => '18pt', 'use-optimal-row-height' => 'true'
105
+ end
106
+
107
+ sheet.table 'Red text table' do |t|
108
+ t.row style: 'row-height' do |r|
109
+ r.cell 'Red', style: 'red-cell'
110
+ end
111
+ end
112
+
113
+ sheet.table 'Text with Paragraphs' do |t|
114
+ t.row style: 'row-height' do |r|
115
+ r.cell do |cell|
116
+ cell.paragraph do |paragraph|
117
+ text_array = my_text_content.split("\n").select{|x| !x.empty? }
118
+
119
+ text_array.each do |str|
120
+ if str.start_with?("#")
121
+ paragraph.span(str, style: 'red-cell')
122
+ else
123
+ paragraph.span(str)
124
+ end
125
+ end
126
+ end
127
+ end
116
128
  end
117
129
  end
130
+
118
131
  end
119
132
  ```
120
133
 
121
134
  Conditional formatting is also possible:
122
135
 
123
136
  ```ruby
124
- require 'rodf'
125
-
126
- RODF::Spreadsheet.file("my-spreadsheet.ods") do
137
+ RODF::Spreadsheet.file("my-spreadsheet.ods") do |sheet|
127
138
 
128
- office_style 'red-cell', family: :cell do
129
- property :text, 'font-weight' => 'bold', 'color' => '#ff0000'
139
+ sheet.office_style 'red-cell', family: :cell do |s|
140
+ s.property :text, 'font-weight' => 'bold', 'color' => '#ff0000'
130
141
  end
131
142
 
132
- office_style 'green-cell', family: :cell do
133
- property :text, 'font-weight' => 'bold', 'color' => '#00ff00'
143
+ sheet.office_style 'green-cell', family: :cell do |s|
144
+ s.property :text, 'font-weight' => 'bold', 'color' => '#00ff00'
134
145
  end
135
146
 
136
147
  # conditional formating must be defined as style and the value of
137
148
  # apply-style-name must be an office_style
138
- style 'cond1', family: :cell do
139
- property :conditional, 'condition' => 'cell-content()<0', 'apply-style-name' => 'red-cell'
149
+ sheet.style 'cond1', family: :cell do |s|
150
+ s.property :conditional, 'condition' => 'cell-content()<0', 'apply-style-name' => 'red-cell'
140
151
 
141
- property :conditional, 'condition' => 'cell-content()>0', 'apply-style-name' => 'green-cell'
152
+ s.property :conditional, 'condition' => 'cell-content()>0', 'apply-style-name' => 'green-cell'
142
153
  end
143
154
 
144
- table 'Red text table' do
145
- row do
146
- cell 'Red force', style: 'red-cell'
155
+ sheet.table 'Red text table' do |t|
156
+ t.row do |r|
157
+ r.cell 'Red force', style: 'red-cell'
147
158
  end
148
- row do
149
- cell '-4', type: :float, style: 'cond1'
159
+ t.row do |r|
160
+ r.cell '-4', type: :float, style: 'cond1'
150
161
  end
151
- row do
152
- cell '0', type: :float, style: 'cond1'
162
+ t.row do |r|
163
+ r.cell '0', type: :float, style: 'cond1'
153
164
  end
154
- row do
155
- cell '5', type: :float, style: 'cond1'
165
+ t.row do |r|
166
+ r.cell '5', type: :float, style: 'cond1'
156
167
  end
157
168
  end
158
169
  end
159
170
  ```
160
171
 
172
+ ## Changing Columns Widths
173
+
174
+ Adding columns or columns width to your spreadsheet can be done with the following
175
+
176
+ ```ruby
177
+ RODF::Spreadsheet.file("my-spreadsheet.ods") do |sheet|
178
+ sheet.table "foo" do |t|
179
+ sheet.style('default-col-width', family: :column) do |s|
180
+ s.property(:column, 'column-width' => '1.234in')
181
+ end
182
+
183
+ col_count.times do
184
+ t.column style: 'default-col-width'
185
+ end
186
+
187
+ ### OR
188
+
189
+ ### Warning this will overwrite any existing table columns (cells remain unaffected)
190
+ sheet.set_column_widths(
191
+ table: t,
192
+ column_widths: [
193
+ {'column-width' => '1in'},
194
+ {'column-width' => '2cm'},
195
+ {'column-width' => '2.54cm'},
196
+ ],
197
+ )
198
+ end
199
+ end
200
+ ```
201
+
161
202
  ## Columns Types
162
203
 
163
204
  Available columns types are:
@@ -171,37 +212,67 @@ Available columns types are:
171
212
 
172
213
  ## Style List
173
214
  ```ruby
174
- property :text,
175
- 'font-weight' => :bold, #options are :bold, :thin
176
- 'font-size' => 12,
177
- 'font-name' => 'Arial',
178
- 'font-style' => 'italic',
179
- 'text-underline-style' => 'solid', # solid, dashed, dotted, double
180
- 'text-underline-type' => 'single',
181
- 'text-line-through-style' => 'solid',
182
- align: true,
183
- color: "#000000"
184
-
185
- property :cell,
186
- 'background-color' => "#DDDDDD",
187
- 'wrap-option' => 'wrap',
188
- 'vertical_align' => 'automatic',
189
- 'border-top' => '0.75pt solid #999999',
190
- 'border-bottom' => '0.75pt solid #999999',
191
- 'border-left' => '0.75pt solid #999999',
192
- 'border-right' => '0.75pt solid #999999',
193
-
194
- property :column,
195
- 'column-width' => '4.0cm'
196
-
197
- property :row,
198
- 'row-height' => '18pt',
199
- 'use-optimal-row-height' => 'true'
200
-
201
- property :table,
202
- 'writing-mode' => 'lr-tb',
215
+ ### family: :cell or "table-cell"
216
+ style "my-cell-style", family: :cell do
217
+ property :text,
218
+ 'font-weight' => :bold, #options are :bold, :thin
219
+ 'font-size' => 12,
220
+ 'font-name' => 'Arial',
221
+ 'font-style' => 'italic',
222
+ 'text-underline-style' => 'solid', # solid, dashed, dotted, double
223
+ 'text-underline-type' => 'single',
224
+ 'text-line-through-style' => 'solid',
225
+ align: true,
226
+ color: "#000000"
227
+
228
+ property :cell,
229
+ 'background-color' => "#DDDDDD",
230
+ 'wrap-option' => 'wrap',
231
+ 'vertical_align' => 'automatic',
232
+ 'border-top' => '0.75pt solid #999999',
233
+ 'border-bottom' => '0.75pt solid #999999',
234
+ 'border-left' => '0.75pt solid #999999',
235
+ 'border-right' => '0.75pt solid #999999',
236
+ 'writing-mode' => 'lr-tb',
237
+
238
+ end
239
+
240
+ ### family: :column or "table-column"
241
+ style('my-col-style', family: :column) do
242
+ property :column,
243
+ 'column-width' => '4.0cm'
244
+ end
245
+
246
+ ### family: :row or "table-row"
247
+ style('my-row-style', family: :row) do
248
+ property :row,
249
+ 'row-height' => '18pt',
250
+ 'use-optimal-row-height' => 'true'
251
+ end
252
+
253
+ ### family: :table
254
+ style('my-row-style', family: :table) do
255
+ property :table,
256
+ 'writing-mode' => 'lr-tb',
203
257
  ```
204
258
 
259
+ ## Adding Arbitrary XML Attributes
260
+
261
+ ```ruby
262
+ RODF::Spreadsheet.file("my-spreadsheet.ods") do |sheet|
263
+ sheet.table 'My first table from Ruby', attributes: {'table-protected' => 'true'} do |table|
264
+ table.row do |row|
265
+ row.cell @data
266
+ end
267
+ end
268
+ end
269
+
270
+ ```
271
+
272
+ ## Production Usage Examples
273
+
274
+ - `spreadsheet_architect` gem - [View Relevant Source Code](https://github.com/westonganger/spreadsheet_architect/blob/master/lib/spreadsheet_architect/class_methods/ods.rb)
275
+
205
276
  ## Credits
206
277
 
207
278
  Originally Created by [@thiagoarrais](https://github.com/thiagoarrais)
data/Rakefile CHANGED
@@ -6,3 +6,10 @@ RSpec::Core::RakeTask.new
6
6
 
7
7
  task :test => :spec
8
8
  task :default => :test
9
+
10
+ task :console do
11
+ require 'rodf'
12
+
13
+ require 'irb'
14
+ binding.irb
15
+ end
data/lib/rodf/cell.rb CHANGED
@@ -1,15 +1,5 @@
1
- require 'date'
2
-
3
- require 'builder'
4
-
5
- require_relative 'container'
6
- require_relative 'paragraph'
7
-
8
1
  module RODF
9
2
  class Cell < Container
10
- contains :paragraphs
11
-
12
- alias :p :paragraph
13
3
 
14
4
  def initialize(value=nil, opts={})
15
5
  super
@@ -25,6 +15,7 @@ module RODF
25
15
  end
26
16
 
27
17
  @value = value || ''
18
+
28
19
  @type = opts[:type]
29
20
 
30
21
  unless empty?(@value)
@@ -46,21 +37,58 @@ module RODF
46
37
  ### TODO: set default DataStyle for the Spreadsheet for Date / Time / DateTime cells formatting
47
38
 
48
39
  @elem_attrs = make_element_attributes(@type, @value, opts)
40
+
41
+ if opts[:attributes]
42
+ @elem_attrs.merge!(opts[:attributes])
43
+ end
44
+
49
45
  @multiplier = (opts[:span] || 1).to_i
50
46
 
51
47
  make_value_paragraph
52
48
  end
53
49
 
50
+ def paragraphs
51
+ @paragraphs ||= []
52
+ end
53
+
54
+ def paragraph(*args, &block)
55
+ x = Paragraph.new(*args, &block)
56
+
57
+ paragraphs << x
58
+
59
+ return x
60
+ end
61
+ alias p paragraph
62
+
63
+ def paragraphs_xml
64
+ paragraphs.map(&:xml).join
65
+ end
66
+
67
+ def add_paragraphs(*elements)
68
+ if elements.first.is_a?(Array)
69
+ elements = elements.first
70
+ end
71
+
72
+ elements.each do |element|
73
+ paragraph(element)
74
+ end
75
+ end
76
+
54
77
  def style=(style_name)
55
78
  @elem_attrs['table:style-name'] = style_name
56
79
  end
57
80
 
58
81
  def xml
59
82
  markup = Builder::XmlMarkup.new
83
+
60
84
  text = markup.tag! 'table:table-cell', @elem_attrs do |xml|
61
85
  xml << paragraphs_xml
62
86
  end
63
- (@multiplier - 1).times {text = markup.tag! 'table:table-cell'}
87
+
88
+ (@multiplier - 1).times do
89
+ text = markup.tag! 'table:table-cell'
90
+ end
91
+
64
92
  text
65
93
  end
66
94
 
@@ -68,7 +96,7 @@ module RODF
68
96
  !empty?(@url)
69
97
  end
70
98
 
71
- private
99
+ private
72
100
 
73
101
  def make_element_attributes(type, value, opts)
74
102
  attrs = {}
data/lib/rodf/column.rb CHANGED
@@ -1,10 +1,17 @@
1
- require 'builder'
2
-
3
1
  module RODF
4
2
  class Column
5
3
  def initialize(opts={})
6
4
  @elem_attrs = {}
5
+
7
6
  @elem_attrs['table:style-name'] = opts[:style] unless opts[:style].nil?
7
+
8
+ if opts[:attributes]
9
+ @elem_attrs.merge!(opts[:attributes])
10
+ end
11
+ end
12
+
13
+ def style=(style_name)
14
+ @elem_attrs['table:style-name'] = style_name
8
15
  end
9
16
 
10
17
  def xml
@@ -1,60 +1,5 @@
1
- require 'dry/inflector'
2
-
3
1
  module RODF
4
2
  class Container
5
- INFLECTOR = Dry::Inflector.new.freeze
6
-
7
- def self.contains(*stuffs_array)
8
- stuffs_array.map {|sym| sym.to_s}.each do |stuffs|
9
- stuff = INFLECTOR.singularize(stuffs.to_s)
10
- stuff_class = RODF.const_get(INFLECTOR.camelize(stuff))
11
-
12
- module_for_stuff.instance_exec do
13
- define_method stuffs do
14
- instance_variable_name = :"@#{stuffs}"
15
-
16
- if instance_variable_defined?(instance_variable_name)
17
- return instance_variable_get(instance_variable_name)
18
- end
19
-
20
- instance_variable_set(instance_variable_name, [])
21
- end
22
-
23
- define_method stuff do |*args, &contents|
24
- c = stuff_class.new(*args, &contents)
25
- public_send(stuffs) << c
26
- c
27
- end
28
-
29
- define_method "add_#{stuffs}" do |*elements|
30
- elements = elements.first if elements.first.is_a?(Array)
31
- elements.each do |element|
32
- public_send(stuff, element)
33
- end
34
- end
35
-
36
- define_method "#{stuffs}_xml" do
37
- public_send(stuffs).map(&:xml).join
38
- end
39
- end
40
- end
41
- end
42
-
43
- def self.module_for_stuff
44
- if const_defined?(:StuffMethods, false)
45
- mod = const_get(:StuffMethods)
46
- else
47
- mod = const_set(:StuffMethods, Module.new)
48
- include mod
49
- end
50
- mod
51
- end
52
-
53
- def self.create(*args, &contents)
54
- container = new(*args, &contents)
55
- container.xml
56
- end
57
-
58
3
  def initialize(*_args, &contents)
59
4
  return unless contents
60
5
 
@@ -64,5 +9,10 @@ module RODF
64
9
  yield(self)
65
10
  end
66
11
  end
12
+
13
+ def self.create(*args, &contents)
14
+ container = self.new(*args, &contents)
15
+ container.xml
16
+ end
67
17
  end
68
18
  end
@@ -1,20 +1,38 @@
1
- require 'builder'
2
-
3
- require_relative 'container'
4
- require_relative 'style_section'
5
-
6
1
  module RODF
7
2
  class DataStyle < Container
8
- contains :style_sections
9
-
10
- alias section style_section
11
-
12
3
  def initialize(name, type)
13
4
  super
14
5
 
15
6
  @type, @name = type, name
16
7
  end
17
8
 
9
+ def style_sections
10
+ @style_sections ||= []
11
+ end
12
+
13
+ def style_section(*args, &block)
14
+ x = StyleSection.new(*args, &block)
15
+
16
+ style_sections << x
17
+
18
+ return x
19
+ end
20
+ alias section style_section
21
+
22
+ def style_sections_xml
23
+ style_sections.map(&:xml).join
24
+ end
25
+
26
+ def add_style_sections(*elements)
27
+ if elements.first.is_a?(Array)
28
+ elements = elements.first
29
+ end
30
+
31
+ elements.each do |element|
32
+ style_section(element)
33
+ end
34
+ end
35
+
18
36
  def xml
19
37
  Builder::XmlMarkup.new.tag! "number:#{@type}-style", 'style:name' => @name do |xml|
20
38
  xml << style_sections_xml