osheet 0.10.0 → 1.0.0.rc.1

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.
Files changed (75) hide show
  1. data/Gemfile +0 -1
  2. data/Gemfile.lock +9 -6
  3. data/Rakefile +35 -19
  4. data/bench/bench_runner.rb +91 -0
  5. data/bench/profiler_runner.rb +1 -0
  6. data/examples/basic.rb +1 -1
  7. data/examples/basic.xls +2 -1
  8. data/examples/basic_with_templates.rb +2 -2
  9. data/examples/basic_with_templates.xls +3 -3
  10. data/examples/formats.rb +2 -2
  11. data/examples/formats.xls +46 -46
  12. data/examples/formula.rb +2 -2
  13. data/examples/styles.rb +2 -2
  14. data/examples/styles.xls +5 -5
  15. data/examples/trivial.rb +2 -2
  16. data/lib/osheet/cell.rb +48 -46
  17. data/lib/osheet/column.rb +23 -29
  18. data/lib/osheet/format.rb +3 -3
  19. data/lib/osheet/meta_element.rb +2 -1
  20. data/lib/osheet/mixin.rb +21 -9
  21. data/lib/osheet/partial.rb +5 -9
  22. data/lib/osheet/row.rb +28 -32
  23. data/lib/osheet/style.rb +11 -25
  24. data/lib/osheet/styled_element.rb +9 -1
  25. data/lib/osheet/template.rb +3 -8
  26. data/lib/osheet/version.rb +1 -1
  27. data/lib/osheet/workbook.rb +135 -43
  28. data/lib/osheet/workbook_api.rb +208 -0
  29. data/lib/osheet/workbook_element.rb +225 -8
  30. data/lib/osheet/worksheet.rb +22 -28
  31. data/lib/osheet/xmlss_writer/style_cache.rb +64 -0
  32. data/lib/osheet/xmlss_writer/style_settings.rb +148 -0
  33. data/lib/osheet/xmlss_writer.rb +143 -1
  34. data/lib/osheet.rb +3 -29
  35. data/osheet.gemspec +4 -1
  36. data/test/cell_test.rb +33 -98
  37. data/test/column_test.rb +20 -88
  38. data/test/{mixins.rb → fixtures/mixins.rb} +6 -4
  39. data/test/fixtures/test_writer.rb +68 -0
  40. data/test/format_test.rb +2 -2
  41. data/test/helper.rb +34 -68
  42. data/test/mixin_test.rb +37 -43
  43. data/test/partial_test.rb +3 -26
  44. data/test/row_test.rb +32 -85
  45. data/test/style_test.rb +9 -26
  46. data/test/template_test.rb +5 -6
  47. data/test/workbook_element_test.rb +231 -0
  48. data/test/workbook_test.rb +225 -116
  49. data/test/worksheet_test.rb +51 -98
  50. data/test/xmlss_writer/api_test.rb +139 -0
  51. data/test/xmlss_writer/style_cache_test.rb +65 -0
  52. data/test/xmlss_writer/style_settings_test.rb +263 -0
  53. data/test/xmlss_writer/styles_test.rb +121 -153
  54. data/test/xmlss_writer_test.rb +91 -0
  55. metadata +75 -50
  56. data/lib/osheet/associations.rb +0 -58
  57. data/lib/osheet/instance.rb +0 -30
  58. data/lib/osheet/markup_element.rb +0 -22
  59. data/lib/osheet/partial_set.rb +0 -57
  60. data/lib/osheet/railtie.rb +0 -9
  61. data/lib/osheet/style_set.rb +0 -39
  62. data/lib/osheet/template_set.rb +0 -51
  63. data/lib/osheet/view_handler/rails.rb +0 -44
  64. data/lib/osheet/view_handler/tilt.rb +0 -42
  65. data/lib/osheet/view_handler.rb +0 -2
  66. data/lib/osheet/worksheet_element.rb +0 -17
  67. data/lib/osheet/xmlss_writer/base.rb +0 -49
  68. data/lib/osheet/xmlss_writer/elements.rb +0 -56
  69. data/lib/osheet/xmlss_writer/styles.rb +0 -216
  70. data/test/osheet_test.rb +0 -13
  71. data/test/partial_set_test.rb +0 -64
  72. data/test/style_set_test.rb +0 -47
  73. data/test/template_set_test.rb +0 -74
  74. data/test/xmlss_writer/base_test.rb +0 -103
  75. data/test/xmlss_writer/elements_test.rb +0 -172
data/lib/osheet/cell.rb CHANGED
@@ -1,62 +1,64 @@
1
1
  require 'date'
2
+
2
3
  require 'osheet/format'
4
+ require 'osheet/meta_element'
5
+ require 'osheet/styled_element'
3
6
 
4
7
  module Osheet
5
8
  class Cell
6
- include Instance
7
- include WorkbookElement
8
- include WorksheetElement
9
+
10
+ include MetaElement
9
11
  include StyledElement
10
- include MarkupElement
11
-
12
- def initialize(workbook=nil, worksheet=nil, *args, &block)
13
- set_ivar(:workbook, workbook)
14
- set_ivar(:worksheet, worksheet)
15
- set_ivar(:data, nil)
16
- set_ivar(:format, Format.new(:general))
17
- set_ivar(:rowspan, 1)
18
- set_ivar(:colspan, 1)
19
- set_ivar(:href, nil)
20
- set_ivar(:index, nil)
21
- set_ivar(:formula, nil)
22
- if block_given?
23
- set_binding_ivars(block.binding)
24
- instance_exec(*args, &block)
25
- end
12
+
13
+ def initialize(data_value=nil)
14
+ @data = cast_data_value(data_value)
15
+ @format = Format.new(:general)
16
+ @rowspan = 1
17
+ @colspan = 1
18
+ @index = nil
19
+ @href = nil
20
+ @formula = nil
21
+ end
22
+
23
+ def data(value=nil)
24
+ value.nil? ? @data : @data = cast_data_value(value)
25
+ end
26
+
27
+ def format(value=nil, opts={})
28
+ value.nil? ? @format : @format = Format.new(value, opts)
29
+ end
30
+
31
+ def rowspan(value=nil)
32
+ value.nil? ? @rowspan : @rowspan = value
26
33
  end
27
34
 
28
- def data(value)
29
- set_ivar(:data, case value
30
- when ::String, ::Numeric, ::Date, ::Time, ::DateTime
35
+ def colspan(value=nil)
36
+ value.nil? ? @colspan : @colspan = value
37
+ end
38
+
39
+ def index(value=nil)
40
+ value.nil? ? @index : @index = value
41
+ end
42
+
43
+ def href(value=nil)
44
+ value.nil? ? @href : @href = value
45
+ end
46
+
47
+ def formula(value=nil)
48
+ value.nil? ? @formula : @formula = value
49
+ end
50
+
51
+ private
52
+
53
+ def cast_data_value(value)
54
+ case value
55
+ when ::String, ::Numeric, ::Date, ::Time, ::DateTime, ::NilClass
31
56
  value
32
57
  when ::Symbol
33
58
  value.to_s
34
59
  else
35
60
  value.inspect.to_s
36
- end)
37
- end
38
-
39
- def format(type, opts={})
40
- set_ivar(:format, Format.new(type, opts))
41
- end
42
-
43
- def rowspan(value); set_ivar(:rowspan, value); end
44
- def colspan(value); set_ivar(:colspan, value); end
45
- def href(value); set_ivar(:href, value); end
46
- def index(value); set_ivar(:index, value); end
47
- def formula(value); set_ivar(:formula, value); end
48
-
49
- def attributes
50
- {
51
- :style_class => get_ivar(:style_class),
52
- :data => get_ivar(:data),
53
- :format => get_ivar(:format),
54
- :colspan => get_ivar(:colspan),
55
- :rowspan => get_ivar(:rowspan),
56
- :href => get_ivar(:href),
57
- :index => get_ivar(:index),
58
- :formula => get_ivar(:formula)
59
- }
61
+ end
60
62
  end
61
63
 
62
64
  end
data/lib/osheet/column.rb CHANGED
@@ -1,40 +1,34 @@
1
+ require 'osheet/meta_element'
2
+ require 'osheet/styled_element'
3
+
1
4
  module Osheet
2
5
  class Column
3
- include Instance
4
- include WorkbookElement
5
- include WorksheetElement
6
- include StyledElement
6
+
7
7
  include MetaElement
8
- include MarkupElement
9
-
10
- def initialize(workbook=nil, worksheet=nil, *args, &block)
11
- set_ivar(:workbook, workbook)
12
- set_ivar(:worksheet, worksheet)
13
- set_ivar(:width, nil)
14
- set_ivar(:autofit, false)
15
- set_ivar(:hidden, false)
16
- if block_given?
17
- set_binding_ivars(block.binding)
18
- instance_exec(*args, &block)
19
- end
8
+ include StyledElement
9
+
10
+ attr_reader :format
11
+
12
+ def initialize(width=nil)
13
+ @width = width
14
+ @autofit = false
15
+ @hidden = false
16
+ @format = Format.new(:general)
20
17
  end
21
18
 
22
19
  def width(value=nil)
23
- !value.nil? ? set_ivar(:width, value) : get_ivar(:width)
20
+ value.nil? ? @width : @width = value
21
+ end
22
+
23
+ def autofit(value=nil)
24
+ value.nil? ? @autofit : @autofit = !!value
24
25
  end
25
- def autofit(value); set_ivar(:autofit, !!value); end
26
- def autofit?; get_ivar(:autofit); end
27
- def hidden(value); set_ivar(:hidden, !!value); end
28
- def hidden?; get_ivar(:hidden); end
29
-
30
- def attributes
31
- {
32
- :style_class => get_ivar(:style_class),
33
- :width => get_ivar(:width),
34
- :autofit => get_ivar(:autofit),
35
- :hidden => get_ivar(:hidden)
36
- }
26
+ def autofit?; @autofit; end
27
+
28
+ def hidden(value=nil)
29
+ value.nil? ? @hidden : @hidden = !!value
37
30
  end
31
+ def hidden?; @hidden; end
38
32
 
39
33
  end
40
34
  end
data/lib/osheet/format.rb CHANGED
@@ -13,17 +13,17 @@ require 'osheet/format/custom'
13
13
  module Osheet::Format
14
14
 
15
15
  VALUES = [
16
- :general,:number, :currency, :accounting,
16
+ :general, :number, :currency, :accounting,
17
17
  :datetime, :percentage, :fraction, :scientific,
18
18
  :text, :special, :custom
19
19
  ]
20
20
 
21
21
  class << self
22
- def new(type, opts={})
22
+ def new(type, *args)
23
23
  unless VALUES.include?(type)
24
24
  raise ArgumentError, "'#{type.inspect}' is not a valid format type"
25
25
  end
26
- self.const_get(type.to_s.capitalize).new(opts)
26
+ self.const_get(type.to_s.capitalize).new(*args)
27
27
  end
28
28
  end
29
29
 
@@ -1,7 +1,8 @@
1
+ module Osheet; end
1
2
  module Osheet::MetaElement
2
3
 
3
4
  def meta(value=nil)
4
- value.nil? ? get_ivar(:meta) : set_ivar(:meta, value)
5
+ value.nil? ? instance_variable_get("@meta") : instance_variable_set("@meta", value)
5
6
  end
6
7
 
7
8
  end
data/lib/osheet/mixin.rb CHANGED
@@ -1,36 +1,48 @@
1
- require 'osheet/style'
2
- require 'osheet/template'
3
-
4
1
  module Osheet::Mixin
5
2
 
6
3
  def self.included(receiver)
7
4
  receiver.send(:extend, ClassMethods)
8
5
  end
9
6
 
7
+ class Args
8
+
9
+ attr_reader :args, :build
10
+
11
+ def initialize(*args, &build)
12
+ @args = args
13
+ @build = build || Proc.new {}
14
+ end
15
+
16
+ end
17
+
10
18
  module ClassMethods
11
- def style(*selectors, &block)
19
+
20
+ def style(*selectors, &build)
12
21
  instance_variable_set("@s",
13
- (instance_variable_get("@s") || []) << ::Osheet::Style.new(*selectors, &block)
22
+ (instance_variable_get("@s") || []) << Args.new(*selectors, &build)
14
23
  )
15
24
  end
25
+
16
26
  def styles
17
27
  instance_variable_get("@s") || []
18
28
  end
19
29
 
20
- def template(element, name, &block)
30
+ def template(element, name, &build)
21
31
  instance_variable_set("@t",
22
- (instance_variable_get("@t") || []) << ::Osheet::Template.new(element, name, &block)
32
+ (instance_variable_get("@t") || []) << Args.new(element, name, &build)
23
33
  )
24
34
  end
35
+
25
36
  def templates
26
37
  instance_variable_get("@t") || []
27
38
  end
28
39
 
29
- def partial(name, &block)
40
+ def partial(name, &build)
30
41
  instance_variable_set("@p",
31
- (instance_variable_get("@p") || []) << ::Osheet::Partial.new(name, &block)
42
+ (instance_variable_get("@p") || []) << Args.new(name, &build)
32
43
  )
33
44
  end
45
+
34
46
  def partials
35
47
  instance_variable_get("@p") || []
36
48
  end
@@ -2,23 +2,19 @@ module Osheet
2
2
  class Partial < ::Proc
3
3
 
4
4
  # this class is essentially a way to define a named definition
5
- # block with arguments. If the partial is added to an element,
6
- # any markup in it's definition block is applied to the element.
7
- # ie. the definition block will be instance_eval'd on the element.
8
-
9
- include Instance
5
+ # block with arguments. If the partial is added to an element,
6
+ # any markup in it's definition block is applied to the element.
7
+ # ie. the definition block will be instance_eval'd on workbook.
10
8
 
11
9
  def initialize(name)
12
10
  unless name.kind_of?(::String) || name.kind_of?(::Symbol)
13
11
  raise ArgumentError, "please use a string or symbol for the partial name."
14
12
  end
15
13
 
16
- set_ivar(:name, name.to_s)
14
+ @name = name.to_s
17
15
  super()
18
16
  end
19
17
 
20
- def name; get_ivar(:name); end
21
- def name=(v); set_ivar(:name, v); end
22
-
23
18
  end
24
19
  end
20
+
data/lib/osheet/row.rb CHANGED
@@ -1,44 +1,40 @@
1
+ require 'osheet/meta_element'
2
+ require 'osheet/styled_element'
3
+
1
4
  require 'osheet/cell'
2
5
 
3
6
  module Osheet
4
7
  class Row
5
- include Instance
6
- include Associations
7
- include WorkbookElement
8
- include WorksheetElement
9
- include StyledElement
8
+
10
9
  include MetaElement
11
- include MarkupElement
12
-
13
- hm :cells
14
-
15
- def initialize(workbook=nil, worksheet=nil, *args, &block)
16
- set_ivar(:workbook, workbook)
17
- set_ivar(:worksheet, worksheet)
18
- set_ivar(:height, nil)
19
- set_ivar(:autofit, false)
20
- set_ivar(:hidden, false)
21
- if block_given?
22
- set_binding_ivars(block.binding)
23
- instance_exec(*args, &block)
24
- end
10
+ include StyledElement
11
+
12
+ attr_reader :cells, :format
13
+
14
+ def initialize(height=nil)
15
+ @height = height
16
+ @autofit = false
17
+ @hidden = false
18
+ @cells = []
19
+ @format = Format.new(:general)
25
20
  end
26
21
 
27
22
  def height(value=nil)
28
- !value.nil? ? set_ivar(:height, value) : get_ivar(:height)
23
+ value.nil? ? @height : @height = value
29
24
  end
30
- def autofit(value); set_ivar(:autofit, !!value); end
31
- def autofit?; get_ivar(:autofit); end
32
- def hidden(value); set_ivar(:hidden, !!value); end
33
- def hidden?; get_ivar(:hidden); end
34
-
35
- def attributes
36
- {
37
- :style_class => get_ivar(:style_class),
38
- :height => get_ivar(:height),
39
- :autofit => get_ivar(:autofit),
40
- :hidden => get_ivar(:hidden)
41
- }
25
+
26
+ def autofit(value=nil)
27
+ value.nil? ? @autofit : @autofit = !!value
28
+ end
29
+ def autofit?; @autofit; end
30
+
31
+ def hidden(value=nil)
32
+ value.nil? ? @hidden : @hidden = !!value
33
+ end
34
+ def hidden?; @hidden; end
35
+
36
+ def cell(cell_obj)
37
+ @cells << cell_obj
42
38
  end
43
39
 
44
40
  end
data/lib/osheet/style.rb CHANGED
@@ -2,45 +2,31 @@ module Osheet
2
2
  class Style
3
3
 
4
4
  # this class is essentially a set of collectors for style settings
5
- # each setting collects any arguments passed to it and
6
- # it is up to the drivers to determine how to use the settings
7
-
8
- include Instance
5
+ # each setting collects any arguments passed to it and
6
+ # it is up to the writer to determine how to use the settings
9
7
 
10
8
  BORDER_POSITIONS = [:top, :right, :bottom, :left]
11
9
  BORDERS = BORDER_POSITIONS.collect{|p| "border_#{p}".to_sym}
12
10
  SETTINGS = [:align, :font, :bg] + BORDERS
13
11
 
14
- def initialize(*selectors, &block)
15
- set_ivar(:selectors, verify(selectors))
16
- SETTINGS.each {|setting| set_ivar(setting, [])}
17
- if block_given?
18
- set_binding_ivars(block.binding)
19
- instance_eval(&block)
20
- end
21
- end
12
+ attr_reader :selectors, :build
22
13
 
23
- def selectors
24
- get_ivar(:selectors)
14
+ def initialize(*selectors, &build)
15
+ @selectors = verify(selectors)
16
+ @build = build || Proc.new {}
17
+ SETTINGS.each { |s| instance_variable_set("@#{s}", []) }
25
18
  end
26
19
 
27
20
  SETTINGS.each do |setting|
28
21
  define_method(setting) do |*args|
29
- set_ivar(setting, get_ivar(setting) + args)
22
+ instance_variable_get("@#{setting}").tap do |value|
23
+ instance_variable_set("@#{setting}", value + args) if !args.empty?
24
+ end
30
25
  end
31
26
  end
32
27
 
33
28
  def border(*args)
34
- BORDERS.each do |border|
35
- send(border, *args)
36
- end
37
- end
38
-
39
- def attributes
40
- SETTINGS.inject({}) do |attrs, s|
41
- attrs[s] = get_ivar(s)
42
- attrs
43
- end
29
+ BORDERS.each { |border| send(border, *args) }
44
30
  end
45
31
 
46
32
  def match?(style_class)
@@ -1,5 +1,13 @@
1
+ module Osheet; end
1
2
  module Osheet::StyledElement
2
- def style_class(value); set_ivar(:style_class, verify_style_class(value)); end
3
+
4
+ def style_class(value=nil)
5
+ if value.nil?
6
+ instance_variable_get("@style_class")
7
+ else
8
+ instance_variable_set("@style_class", verify_style_class(value))
9
+ end
10
+ end
3
11
 
4
12
  private
5
13
 
@@ -4,10 +4,8 @@ module Osheet
4
4
  class Template < Partial
5
5
 
6
6
  # this class is a partial that is associated with an osheet element
7
- # if an element is initialized from a template, the template
8
- # block will be instance_eval'd for the element being initialized
9
-
10
- include Instance
7
+ # if an element is initialized from a template, the template
8
+ # block will be instance_eval'd for the element being initialized
11
9
 
12
10
  ELEMENTS = ['worksheet', 'column', 'row', 'cell']
13
11
 
@@ -16,12 +14,9 @@ module Osheet
16
14
  raise ArgumentError, "you can only define a template for #{ELEMENTS.join(', ')} elements."
17
15
  end
18
16
 
19
- set_ivar(:element, element.to_s)
17
+ @element = element.to_s
20
18
  super(name)
21
19
  end
22
20
 
23
- def element; get_ivar(:element); end
24
- def element=(v); set_ivar(:element, v); end
25
-
26
21
  end
27
22
  end
@@ -1,3 +1,3 @@
1
1
  module Osheet
2
- VERSION = "0.10.0"
2
+ VERSION = "1.0.0.rc.1"
3
3
  end
@@ -1,65 +1,157 @@
1
- require 'osheet/instance'
2
- require 'osheet/associations'
3
- require 'osheet/markup_element'
4
- require 'osheet/style_set'
5
- require 'osheet/template_set'
6
- require 'osheet/partial_set'
7
- require 'osheet/worksheet'
8
- require 'osheet/xmlss_writer'
1
+ require 'osheet/partial'
2
+ require 'osheet/template'
3
+ require 'osheet/workbook_element'
4
+ require 'osheet/workbook_api'
9
5
 
10
6
  module Osheet
7
+
8
+
11
9
  class Workbook
12
- include Instance
13
- include Associations
14
- include MarkupElement
15
-
16
- hm :worksheets
17
-
18
- def initialize(&block)
19
- set_ivar(:title, nil)
20
- set_ivar(:styles, StyleSet.new)
21
- set_ivar(:templates, TemplateSet.new)
22
- set_ivar(:partials, PartialSet.new)
23
- if block_given?
24
- set_binding_ivars(block.binding)
25
- instance_eval(&block)
10
+
11
+ # This 'Workbook' class is really just a scope for workbook builds to run
12
+ # in. All actually workbook metadata is behavior is handled by the
13
+ # 'WorkbookElement' class
14
+
15
+ class ElementStack < ::Array; end
16
+
17
+ include WorkbookApi
18
+
19
+ def initialize(writer=nil, data={}, &build)
20
+ # apply :data options to workbook scope
21
+ data ||= {}
22
+ if (data.keys.map(&:to_s) & self.public_methods.map(&:to_s)).size > 0
23
+ raise ArgumentError, "data conflicts with workbook public methods."
26
24
  end
27
- end
25
+ metaclass = class << self; self; end
26
+ data.each {|key, value| metaclass.class_eval { define_method(key){value} }}
28
27
 
29
- def title(value=nil)
30
- !value.nil? ? set_ivar(:title, value) : get_ivar(:title)
31
- end
28
+ # setup the writer, element stack, and workbook_element
29
+ writer.bind(self) if writer
30
+ set_ivar(:writer, writer)
31
+ set_ivar(:element_stack, Workbook::ElementStack.new)
32
+ set_ivar(:workbook_element, WorkbookElement.new)
33
+
34
+ # push the workbook element onto the element stack
35
+ element_stack.push(workbook)
32
36
 
33
- def style(*selectors, &block); push_ivar(:styles, Style.new(*selectors, &block)); end
34
- def styles
35
- get_ivar(:styles)
37
+ # run any instance workbook build given
38
+ instance_eval(&build) if build
36
39
  end
37
- def template(element, name, &block); push_ivar(:templates, Template.new(element, name, &block)); end
38
- def templates
39
- get_ivar(:templates)
40
+
41
+ def writer
42
+ get_ivar(:writer)
40
43
  end
41
- def partial(name, &block); push_ivar(:partials, Partial.new(name, &block)); end
42
- def partials
43
- get_ivar(:partials)
44
+
45
+ def element_stack
46
+ get_ivar(:element_stack)
44
47
  end
45
48
 
46
- def attributes
47
- { :title => get_ivar(:title) }
49
+ def workbook_element
50
+ get_ivar(:workbook_element)
48
51
  end
52
+ alias_method :workbook, :workbook_element
49
53
 
54
+ # use a mixin to define its markup handlers (templates, partials, and styles)
55
+ # in your workbook scope
56
+ # all blocks in mixins will be instance eval'd in the workbook scope
57
+ # and should be written as such
50
58
  def use(mixin)
51
- (mixin.styles || []).each{ |s| push_ivar(:styles, s) }
52
- (mixin.templates || []).each{ |t| push_ivar(:templates, t) }
53
- (mixin.partials || []).each{ |p| push_ivar(:partials, p) }
59
+ # templates and partials are just blocks themselves so they just need to
60
+ # be added to the workbook element
61
+ # they will be instance eval'd when they get used
62
+ (mixin.templates || []).each { |mt| template(*mt.args, &mt.build) }
63
+ (mixin.partials || []).each { |mp| partial(*mp.args, &mp.build) }
64
+
65
+ # styles not only need to be added to the workbook element, but
66
+ # any build passed to the style needs to be instance eval'd
67
+ (mixin.styles || []).each do |ms|
68
+ StyleBuild.new(self, *ms.args, &ms.build).add do |build|
69
+ instance_eval(&build)
70
+ end
71
+ end
54
72
  end
55
73
 
56
- def writer
57
- XmlssWriter::Base.new(:workbook => self)
74
+ # add partials to dynamically add markup to your workbook
75
+ # note: you can also define element templates to add element specific
76
+ # markup to your workbook
77
+ def add(partial_name, *args)
78
+ workbook.partials.get(partial_name).tap do |p|
79
+ instance_exec(*args, &p) if p
80
+ end
81
+ end
82
+
83
+ # overriding to make less noisy
84
+ def to_str(*args)
85
+ "#<Osheet::Workbook:#{self.object_id} @title=#{workbook.title.inspect}, " +
86
+ "worksheet_count=#{workbook.worksheets.size.inspect}, " +
87
+ "style_count=#{workbook.styles.size.inspect}>"
58
88
  end
89
+ alias_method :inspect, :to_str
59
90
 
60
- [:to_data, :to_file].each do |meth|
91
+ # writers are responsible for defining what each of these methods do
92
+ # and what they return
93
+ [:to_s, :to_data, :to_file].each do |meth|
61
94
  define_method(meth) {|*args| writer.send(meth, *args) }
62
95
  end
63
96
 
97
+ private
98
+
99
+ OSHEET_IVAR_NS = "_osheet_"
100
+
101
+ def get_ivar(name)
102
+ instance_variable_get(ivar_name(name))
103
+ end
104
+
105
+ def set_ivar(name, value)
106
+ instance_variable_set(ivar_name(name), value)
107
+ end
108
+
109
+ def push_ivar(name, value)
110
+ get_ivar(name) << value
111
+ end
112
+
113
+ def ivar_name(name)
114
+ "@#{OSHEET_IVAR_NS}#{name}"
115
+ end
116
+
117
+ end
118
+
119
+
120
+
121
+ class Workbook::ElementStack
122
+
123
+ # this class is just a wrapper to Array. I want to treat this as a
124
+ # stack of objects for the workbook DSL to reference. I need to push
125
+ # an object onto the stack, reference it using the 'current' method,
126
+ # and pop it off the stack when I'm done.
127
+
128
+ def initialize
129
+ super
130
+ end
131
+
132
+ def push(*args)
133
+ super
134
+ end
135
+
136
+ def pop(*args)
137
+ super
138
+ end
139
+
140
+ def current
141
+ self.last
142
+ end
143
+
144
+ def size(*args)
145
+ super
146
+ end
147
+
148
+ def using(obj, &block)
149
+ push(obj)
150
+ block.call if !block.nil?
151
+ pop
152
+ end
153
+
64
154
  end
155
+
156
+
65
157
  end