rubyXL 2.2.0 → 2.3.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.
Files changed (238) hide show
  1. data/VERSION +1 -1
  2. data/lib/rubyXL/objects/border.rb +3 -3
  3. data/lib/rubyXL/objects/chartsheet.rb +20 -5
  4. data/lib/rubyXL/objects/fill.rb +3 -3
  5. data/lib/rubyXL/objects/filters.rb +5 -5
  6. data/lib/rubyXL/objects/font.rb +3 -3
  7. data/lib/rubyXL/objects/ooxml_object.rb +209 -138
  8. data/lib/rubyXL/objects/relationships.rb +2 -2
  9. data/lib/rubyXL/objects/sheet_common.rb +2 -2
  10. data/lib/rubyXL/objects/stylesheet.rb +35 -35
  11. data/lib/rubyXL/objects/workbook.rb +26 -27
  12. data/lib/rubyXL/objects/worksheet.rb +59 -51
  13. data/lib/rubyXL/parser.rb +22 -12
  14. data/lib/rubyXL/workbook.rb +5 -6
  15. data/lib/rubyXL/worksheet.rb +3 -3
  16. data/lib/rubyXL/writer/workbook_writer.rb +2 -2
  17. data/rdoc/README_rdoc.html +1 -1
  18. data/rdoc/RubyXL.html +1 -1
  19. data/rdoc/RubyXL/AExtensionStorageArea.html +1 -1
  20. data/rdoc/RubyXL/Alignment.html +1 -1
  21. data/rdoc/RubyXL/AlternateContent.html +1 -1
  22. data/rdoc/RubyXL/AutoFilter.html +1 -1
  23. data/rdoc/RubyXL/AutoFilterColumn.html +1 -1
  24. data/rdoc/RubyXL/BooleanNode.html +1 -1
  25. data/rdoc/RubyXL/BooleanValue.html +1 -1
  26. data/rdoc/RubyXL/Border.html +1 -1
  27. data/rdoc/RubyXL/BorderEdge.html +1 -1
  28. data/rdoc/RubyXL/{FillContainer.html → Borders.html} +5 -5
  29. data/rdoc/RubyXL/Break.html +1 -1
  30. data/rdoc/RubyXL/BreakList.html +2 -2
  31. data/rdoc/RubyXL/CalculationChain.html +1 -1
  32. data/rdoc/RubyXL/CalculationChainCell.html +1 -1
  33. data/rdoc/RubyXL/CalculationProperties.html +1 -1
  34. data/rdoc/RubyXL/Cell.html +1 -1
  35. data/rdoc/RubyXL/CellSmartTag.html +1 -1
  36. data/rdoc/RubyXL/CellSmartTagProperty.html +1 -1
  37. data/rdoc/RubyXL/CellSmartTags.html +105 -0
  38. data/rdoc/RubyXL/CellStyle.html +1 -1
  39. data/rdoc/RubyXL/CellStyleXFs.html +105 -0
  40. data/rdoc/RubyXL/CellStyles.html +105 -0
  41. data/rdoc/RubyXL/CellValue.html +1 -1
  42. data/rdoc/RubyXL/CellWatch.html +1 -1
  43. data/rdoc/RubyXL/{CellXFContainer.html → CellWatches.html} +5 -5
  44. data/rdoc/RubyXL/CellXFs.html +105 -0
  45. data/rdoc/RubyXL/Chartsheet.html +1 -1
  46. data/rdoc/RubyXL/ChartsheetPageSetup.html +1 -1
  47. data/rdoc/RubyXL/ChartsheetProperties.html +1 -1
  48. data/rdoc/RubyXL/ChartsheetProtection.html +1 -1
  49. data/rdoc/RubyXL/ChartsheetView.html +1 -1
  50. data/rdoc/RubyXL/{BorderContainer.html → ChartsheetViews.html} +4 -4
  51. data/rdoc/RubyXL/Color.html +1 -1
  52. data/rdoc/RubyXL/ColorFilter.html +1 -1
  53. data/rdoc/RubyXL/ColorScale.html +1 -1
  54. data/rdoc/RubyXL/ColorScheme.html +1 -1
  55. data/rdoc/RubyXL/ColorSet.html +1 -1
  56. data/rdoc/RubyXL/Colors.html +1 -1
  57. data/rdoc/RubyXL/ColumnRange.html +1 -1
  58. data/rdoc/RubyXL/ColumnRanges.html +1 -1
  59. data/rdoc/RubyXL/ConditionalFormatValue.html +1 -1
  60. data/rdoc/RubyXL/ConditionalFormatting.html +2 -2
  61. data/rdoc/RubyXL/ConditionalFormattingRule.html +1 -1
  62. data/rdoc/RubyXL/CustomFilter.html +1 -1
  63. data/rdoc/RubyXL/{CustomFilterContainer.html → CustomFilters.html} +5 -5
  64. data/rdoc/RubyXL/{CellStyleXFContainer.html → CustomProperties.html} +5 -5
  65. data/rdoc/RubyXL/CustomProperty.html +1 -1
  66. data/rdoc/RubyXL/CustomSheetView.html +1 -1
  67. data/rdoc/RubyXL/CustomSheetViews.html +2 -2
  68. data/rdoc/RubyXL/CustomWorkbookView.html +1 -1
  69. data/rdoc/RubyXL/{CustomWorkbookViewContainer.html → CustomWorkbookViews.html} +5 -5
  70. data/rdoc/RubyXL/DXF.html +1 -1
  71. data/rdoc/RubyXL/DXFs.html +1 -1
  72. data/rdoc/RubyXL/DataBar.html +1 -1
  73. data/rdoc/RubyXL/DataConsolidate.html +1 -1
  74. data/rdoc/RubyXL/DataConsolidationReference.html +1 -1
  75. data/rdoc/RubyXL/DataConsolidationReferences.html +2 -2
  76. data/rdoc/RubyXL/DataValidation.html +1 -1
  77. data/rdoc/RubyXL/DataValidations.html +1 -1
  78. data/rdoc/RubyXL/DateGroupItem.html +1 -1
  79. data/rdoc/RubyXL/DefinedName.html +1 -1
  80. data/rdoc/RubyXL/DefinedNames.html +2 -2
  81. data/rdoc/RubyXL/DocumentProperties.html +1 -1
  82. data/rdoc/RubyXL/DynamicFilter.html +1 -1
  83. data/rdoc/RubyXL/EmbeddedControl.html +1 -1
  84. data/rdoc/RubyXL/{EmbeddedControlContainer.html → EmbeddedControls.html} +5 -5
  85. data/rdoc/RubyXL/Extension.html +1 -1
  86. data/rdoc/RubyXL/ExtensionStorageArea.html +1 -1
  87. data/rdoc/RubyXL/ExternalReference.html +1 -1
  88. data/rdoc/RubyXL/ExternalReferences.html +2 -2
  89. data/rdoc/RubyXL/FieldItem.html +1 -1
  90. data/rdoc/RubyXL/FileRecoveryProperties.html +1 -1
  91. data/rdoc/RubyXL/FileSharing.html +1 -1
  92. data/rdoc/RubyXL/FileVersion.html +1 -1
  93. data/rdoc/RubyXL/Fill.html +1 -1
  94. data/rdoc/RubyXL/{FontContainer.html → Fills.html} +5 -5
  95. data/rdoc/RubyXL/FilterContainer.html +1 -1
  96. data/rdoc/RubyXL/FloatNode.html +1 -1
  97. data/rdoc/RubyXL/FloatValue.html +1 -1
  98. data/rdoc/RubyXL/Font.html +1 -1
  99. data/rdoc/RubyXL/FontScheme.html +1 -1
  100. data/rdoc/RubyXL/Fonts.html +105 -0
  101. data/rdoc/RubyXL/FormatScheme.html +1 -1
  102. data/rdoc/RubyXL/Formula.html +1 -1
  103. data/rdoc/RubyXL/FunctionGroup.html +1 -1
  104. data/rdoc/RubyXL/{CellWatchContainer.html → FunctionGroups.html} +5 -5
  105. data/rdoc/RubyXL/GenericStorage.html +1 -1
  106. data/rdoc/RubyXL/GradientFill.html +1 -1
  107. data/rdoc/RubyXL/HeaderFooterSettings.html +1 -1
  108. data/rdoc/RubyXL/Hyperlink.html +1 -1
  109. data/rdoc/RubyXL/Hyperlinks.html +105 -0
  110. data/rdoc/RubyXL/IconFilter.html +1 -1
  111. data/rdoc/RubyXL/IconSet.html +1 -1
  112. data/rdoc/RubyXL/IgnoredError.html +1 -1
  113. data/rdoc/RubyXL/IgnoredErrors.html +105 -0
  114. data/rdoc/RubyXL/IndexedColors.html +105 -0
  115. data/rdoc/RubyXL/InputCells.html +1 -1
  116. data/rdoc/RubyXL/IntegerNode.html +1 -1
  117. data/rdoc/RubyXL/IntegerValue.html +1 -1
  118. data/rdoc/RubyXL/LegacyCell.html +1 -1
  119. data/rdoc/RubyXL/LegacyWorkbook.html +25 -25
  120. data/rdoc/RubyXL/LegacyWorksheet.html +3 -29
  121. data/rdoc/RubyXL/{ChartsheetViewContainer.html → MRUColors.html} +5 -5
  122. data/rdoc/RubyXL/MergedCell.html +1 -1
  123. data/rdoc/RubyXL/MergedCells.html +2 -2
  124. data/rdoc/RubyXL/NumFmt.html +1 -1
  125. data/rdoc/RubyXL/NumberFormat.html +1 -1
  126. data/rdoc/RubyXL/{NumberFormatContainer.html → NumberFormats.html} +6 -6
  127. data/rdoc/RubyXL/OLEObject.html +1 -1
  128. data/rdoc/RubyXL/OLEObjects.html +2 -2
  129. data/rdoc/RubyXL/OLESize.html +1 -1
  130. data/rdoc/RubyXL/OOXMLContainerObject.html +105 -0
  131. data/rdoc/RubyXL/OOXMLObject.html +1 -758
  132. data/rdoc/RubyXL/OOXMLObjectClassMethods.html +559 -0
  133. data/rdoc/RubyXL/OOXMLObjectInstanceMethods.html +98 -0
  134. data/rdoc/RubyXL/OOXMLTopLevelObject.html +1 -1
  135. data/rdoc/RubyXL/OutlineProperties.html +1 -1
  136. data/rdoc/RubyXL/PageMargins.html +1 -1
  137. data/rdoc/RubyXL/PageSetup.html +1 -1
  138. data/rdoc/RubyXL/PageSetupProperties.html +1 -1
  139. data/rdoc/RubyXL/Pane.html +1 -1
  140. data/rdoc/RubyXL/Parser.html +23 -13
  141. data/rdoc/RubyXL/PatternFill.html +1 -1
  142. data/rdoc/RubyXL/PhoneticProperties.html +1 -1
  143. data/rdoc/RubyXL/PhoneticRun.html +1 -1
  144. data/rdoc/RubyXL/PivotArea.html +1 -1
  145. data/rdoc/RubyXL/PivotCache.html +1 -1
  146. data/rdoc/RubyXL/PivotCaches.html +2 -2
  147. data/rdoc/RubyXL/PivotReference.html +1 -1
  148. data/rdoc/RubyXL/{CellStyleContainer.html → PivotReferences.html} +5 -5
  149. data/rdoc/RubyXL/PivotTableSelection.html +1 -1
  150. data/rdoc/RubyXL/PrintOptions.html +1 -1
  151. data/rdoc/RubyXL/ProtectedRange.html +1 -1
  152. data/rdoc/RubyXL/ProtectedRanges.html +2 -2
  153. data/rdoc/RubyXL/Protection.html +1 -1
  154. data/rdoc/RubyXL/RID.html +1 -1
  155. data/rdoc/RubyXL/RawOOXML.html +1 -1
  156. data/rdoc/RubyXL/Reference.html +1 -1
  157. data/rdoc/RubyXL/Relationship.html +1 -1
  158. data/rdoc/RubyXL/RichText.html +1 -1
  159. data/rdoc/RubyXL/RichTextRun.html +1 -1
  160. data/rdoc/RubyXL/Row.html +1 -1
  161. data/rdoc/RubyXL/RunProperties.html +1 -1
  162. data/rdoc/RubyXL/Scenario.html +1 -1
  163. data/rdoc/RubyXL/Scenarios.html +105 -0
  164. data/rdoc/RubyXL/Selection.html +1 -1
  165. data/rdoc/RubyXL/SharedStringsTable.html +3 -3
  166. data/rdoc/RubyXL/Sheet.html +1 -1
  167. data/rdoc/RubyXL/SheetCalculationProperties.html +1 -1
  168. data/rdoc/RubyXL/SheetData.html +1 -1
  169. data/rdoc/RubyXL/Sheets.html +2 -2
  170. data/rdoc/RubyXL/SmartTagProperties.html +1 -1
  171. data/rdoc/RubyXL/SmartTagType.html +1 -1
  172. data/rdoc/RubyXL/SmartTagTypes.html +105 -0
  173. data/rdoc/RubyXL/SmartTags.html +105 -0
  174. data/rdoc/RubyXL/SortCondition.html +1 -1
  175. data/rdoc/RubyXL/SortState.html +1 -1
  176. data/rdoc/RubyXL/Sqref.html +1 -1
  177. data/rdoc/RubyXL/Stop.html +1 -1
  178. data/rdoc/RubyXL/StringNode.html +1 -1
  179. data/rdoc/RubyXL/StringValue.html +1 -1
  180. data/rdoc/RubyXL/Stylesheet.html +1 -1
  181. data/rdoc/RubyXL/TableParts.html +2 -2
  182. data/rdoc/RubyXL/TableStyle.html +1 -1
  183. data/rdoc/RubyXL/TableStyles.html +2 -2
  184. data/rdoc/RubyXL/Text.html +1 -1
  185. data/rdoc/RubyXL/Theme.html +1 -1
  186. data/rdoc/RubyXL/ThemeElements.html +1 -1
  187. data/rdoc/RubyXL/Top10.html +1 -1
  188. data/rdoc/RubyXL/Variant.html +1 -1
  189. data/rdoc/RubyXL/Vector.html +1 -1
  190. data/rdoc/RubyXL/VectorValue.html +1 -1
  191. data/rdoc/RubyXL/WebPublishObject.html +1 -1
  192. data/rdoc/RubyXL/{WebPublishObjectContainer.html → WebPublishObjects.html} +5 -5
  193. data/rdoc/RubyXL/WebPublishingItem.html +1 -1
  194. data/rdoc/RubyXL/{WebPublishingItemContainer.html → WebPublishingItems.html} +5 -5
  195. data/rdoc/RubyXL/WebPublishingProperties.html +1 -1
  196. data/rdoc/RubyXL/Workbook.html +1 -1
  197. data/rdoc/RubyXL/WorkbookProperties.html +1 -1
  198. data/rdoc/RubyXL/WorkbookProtection.html +1 -1
  199. data/rdoc/RubyXL/WorkbookRelationships.html +3 -3
  200. data/rdoc/RubyXL/WorkbookView.html +1 -1
  201. data/rdoc/RubyXL/WorkbookViews.html +2 -2
  202. data/rdoc/RubyXL/Worksheet.html +1 -1
  203. data/rdoc/RubyXL/WorksheetDimensions.html +1 -1
  204. data/rdoc/RubyXL/WorksheetFormatProperties.html +1 -1
  205. data/rdoc/RubyXL/WorksheetProperties.html +1 -1
  206. data/rdoc/RubyXL/WorksheetProtection.html +1 -1
  207. data/rdoc/RubyXL/WorksheetView.html +1 -1
  208. data/rdoc/RubyXL/WorksheetViews.html +2 -2
  209. data/rdoc/RubyXL/Writer.html +1 -1
  210. data/rdoc/RubyXL/Writer/ContentTypesWriter.html +1 -1
  211. data/rdoc/RubyXL/Writer/CoreWriter.html +1 -1
  212. data/rdoc/RubyXL/Writer/GenericWriter.html +1 -1
  213. data/rdoc/RubyXL/Writer/RootRelsWriter.html +1 -1
  214. data/rdoc/RubyXL/Writer/StylesWriter.html +1 -1
  215. data/rdoc/RubyXL/Writer/ThemeWriter.html +1 -1
  216. data/rdoc/RubyXL/Writer/WorkbookWriter.html +3 -3
  217. data/rdoc/RubyXL/XF.html +1 -1
  218. data/rdoc/created.rid +19 -20
  219. data/rdoc/index.html +4 -6
  220. data/rdoc/js/search_index.js +1 -1
  221. data/rdoc/table_of_contents.html +89 -132
  222. data/rubyXL.gemspec +30 -29
  223. data/spec/lib/parser_spec.rb +3 -1
  224. data/spec/lib/stylesheet_spec.rb +1 -1
  225. metadata +31 -30
  226. data/lib/rubyXL/writer/worksheet_writer.rb +0 -41
  227. data/rdoc/RubyXL/CellSmartTagContainer.html +0 -105
  228. data/rdoc/RubyXL/CustomPropertyContainer.html +0 -105
  229. data/rdoc/RubyXL/FunctionGroupContainer.html +0 -105
  230. data/rdoc/RubyXL/HyperlinkContainer.html +0 -105
  231. data/rdoc/RubyXL/IgnoredErrorContainer.html +0 -105
  232. data/rdoc/RubyXL/IndexedColorContainer.html +0 -105
  233. data/rdoc/RubyXL/MRUColorContainer.html +0 -105
  234. data/rdoc/RubyXL/PivotReferenceContainer.html +0 -105
  235. data/rdoc/RubyXL/ScenarioContainer.html +0 -105
  236. data/rdoc/RubyXL/SmartTagContainer.html +0 -105
  237. data/rdoc/RubyXL/SmartTagTypeContainer.html +0 -105
  238. data/rdoc/RubyXL/Writer/WorksheetWriter.html +0 -236
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.3.0
@@ -52,12 +52,12 @@ module RubyXL
52
52
  end
53
53
 
54
54
  # http://www.schemacentral.com/sc/ooxml/e-ssml_borders-1.html
55
- class BorderContainer < OOXMLObject
56
- define_child_node(RubyXL::Border, :collection => :with_count, :accessor => :borders)
55
+ class Borders < OOXMLContainerObject
56
+ define_child_node(RubyXL::Border, :collection => :with_count)
57
57
  define_element_name 'borders'
58
58
 
59
59
  def self.defaults
60
- self.new(:borders => [ RubyXL::Border.new ])
60
+ self.new(:_ => [ RubyXL::Border.new ])
61
61
  end
62
62
 
63
63
  end
@@ -49,8 +49,8 @@ module RubyXL
49
49
  end
50
50
 
51
51
  # http://www.schemacentral.com/sc/ooxml/e-ssml_sheetViews-4.html
52
- class ChartsheetViewContainer < OOXMLObject
53
- define_child_node(RubyXL::ChartsheetView, :collection => true, :accessor => :sheet_views)
52
+ class ChartsheetViews < OOXMLObject
53
+ define_child_node(RubyXL::ChartsheetView, :collection => true)
54
54
  define_child_node(RubyXL::ExtensionStorageArea)
55
55
  define_element_name 'sheetViews'
56
56
  end
@@ -58,9 +58,9 @@ module RubyXL
58
58
  # http://www.schemacentral.com/sc/ooxml/e-ssml_chartsheet.html
59
59
  class Chartsheet < OOXMLTopLevelObject
60
60
  define_child_node(RubyXL::ChartsheetProperties)
61
- define_child_node(RubyXL::ChartsheetViewContainer, :accessor => :sheet_view_container)
61
+ define_child_node(RubyXL::ChartsheetViews)
62
62
  define_child_node(RubyXL::ChartsheetProtection)
63
- define_child_node(RubyXL::CustomSheetViews, :accessor => :custom_sheet_view_container)
63
+ define_child_node(RubyXL::CustomSheetViews)
64
64
  define_child_node(RubyXL::PageMargins)
65
65
  define_child_node(RubyXL::ChartsheetPageSetup)
66
66
  define_child_node(RubyXL::HeaderFooterSettings)
@@ -68,11 +68,26 @@ module RubyXL
68
68
  define_child_node(RubyXL::RID, :node_name => :legacyDrawing)
69
69
  define_child_node(RubyXL::RID, :node_name => :legacyDrawingHF)
70
70
  define_child_node(RubyXL::RID, :node_name => :picture)
71
- define_child_node(RubyXL::WebPublishingItemContainer, :accessor => :web_items_container)
71
+ define_child_node(RubyXL::WebPublishingItems)
72
72
  define_child_node(RubyXL::ExtensionStorageArea)
73
73
  define_element_name 'chartsheet'
74
74
  set_namespaces('xmlns' => 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
75
75
  'xmlns:r' => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships')
76
+
77
+ def sheet_index
78
+ @workbook.worksheets.select{ |sheet| sheet.is_a?(self.class) }.index{ |sheet| sheet.equal?(self) }
79
+ end
80
+
81
+ def filepath
82
+ File.join('xl', 'chartsheets', "sheet#{sheet_index + 1}.xml")
83
+ end
84
+
85
+ def rel_type
86
+ 'chartsheet'
87
+ end
88
+
89
+ attr_accessor :workbook, :sheet_name, :sheet_id
90
+
76
91
  end
77
92
 
78
93
  end
@@ -39,12 +39,12 @@ module RubyXL
39
39
  end
40
40
 
41
41
  # http://www.schemacentral.com/sc/ooxml/e-ssml_fills-1.html
42
- class FillContainer < OOXMLObject
43
- define_child_node(RubyXL::Fill, :collection => :with_count, :accessor => :fills)
42
+ class Fills < OOXMLContainerObject
43
+ define_child_node(RubyXL::Fill, :collection => :with_count)
44
44
  define_element_name 'fills'
45
45
 
46
46
  def self.defaults
47
- self.new(:fills => [
47
+ self.new(:_ => [
48
48
  RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'none')),
49
49
  RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'gray125'))
50
50
  ])
@@ -20,7 +20,7 @@ module RubyXL
20
20
  class FilterContainer < OOXMLObject
21
21
  define_attribute(:blank, :bool, :default => false)
22
22
  define_attribute(:calendarType, RubyXL::ST_CalendarType, :default => 'none')
23
- define_child_node(RubyXL::StringValue, :node_name => :filter, :collection => true, :accessor => :filters)
23
+ define_child_node(RubyXL::StringValue, :collection => true, :accessor => :filters, :node_name => :filter)
24
24
  define_child_node(RubyXL::DateGroupItem, :collection => true, :accessor => :date_group_items)
25
25
  define_element_name 'filters'
26
26
  end
@@ -42,9 +42,9 @@ module RubyXL
42
42
  end
43
43
 
44
44
  # http://www.schemacentral.com/sc/ooxml/e-ssml_customFilters-1.html
45
- class CustomFilterContainer < OOXMLObject
46
- define_attribute(:and, :bool, :default => false)
47
- define_child_node(RubyXL::CustomFilter, :collection => true, :accessor => :custom_filters)
45
+ class CustomFilters < OOXMLContainerObject
46
+ define_attribute(:and, :bool, :default => false)
47
+ define_child_node(RubyXL::CustomFilter, :collection => true)
48
48
  define_element_name 'customFilters'
49
49
  end
50
50
 
@@ -77,7 +77,7 @@ module RubyXL
77
77
  define_attribute(:showButton, :bool, :default => true)
78
78
  define_child_node(RubyXL::FilterContainer)
79
79
  define_child_node(RubyXL::Top10)
80
- define_child_node(RubyXL::CustomFilterContainer, :accessor => :custom_filter_container)
80
+ define_child_node(RubyXL::CustomFilters)
81
81
  define_child_node(RubyXL::DynamicFilter)
82
82
  define_child_node(RubyXL::ColorFilter)
83
83
  define_child_node(RubyXL::IconFilter)
@@ -94,12 +94,12 @@ module RubyXL
94
94
  end
95
95
 
96
96
  # http://www.schemacentral.com/sc/ooxml/e-ssml_fonts-1.html
97
- class FontContainer < OOXMLObject
98
- define_child_node(RubyXL::Font, :collection => :with_count, :accessor => :fonts)
97
+ class Fonts < OOXMLContainerObject
98
+ define_child_node(RubyXL::Font, :collection => :with_count)
99
99
  define_element_name 'fonts'
100
100
 
101
101
  def self.defaults
102
- self.new(:fonts => [
102
+ self.new(:_ => [
103
103
  RubyXL::Font.new(:name => RubyXL::StringValue.new(:val => 'Verdana'),
104
104
  :sz => RubyXL::FloatValue.new(:val => 10) ),
105
105
  RubyXL::Font.new(:name => RubyXL::StringValue.new(:val => 'Verdana'),
@@ -1,9 +1,5 @@
1
1
  module RubyXL
2
-
3
- # Parent class for defining OOXML based objects (not unlike Rails' +ActiveRecord+!)
4
- # Most importantly, provides functionality of parsing such objects from XML,
5
- # and marshalling them to XML.
6
- class OOXMLObject
2
+ module OOXMLObjectClassMethods
7
3
  # Get the value of a [sub]class variable if it exists, or create the respective variable
8
4
  # with the passed-in +default+ (or +{}+, if not specified)
9
5
  #
@@ -12,7 +8,7 @@ module RubyXL
12
8
  # addressing variable by name creates it in the context of defining class, while calling
13
9
  # the setter/getter method addresses it in the context of descendant class,
14
10
  # which is what we need.
15
- def self.obtain_class_variable(var_name, default = {})
11
+ def obtain_class_variable(var_name, default = {})
16
12
  if class_variable_defined?(var_name) then
17
13
  self.class_variable_get(var_name)
18
14
  else
@@ -20,11 +16,6 @@ module RubyXL
20
16
  end
21
17
  end
22
18
 
23
- def obtain_class_variable(var_name, default = {})
24
- self.class.obtain_class_variable(var_name, default)
25
- end
26
- private :obtain_class_variable
27
-
28
19
  # Defines an attribute of OOXML object.
29
20
  # === Parameters
30
21
  # * +attribute_name+ - Name of the element attribute as seen in the source XML. Can be either <tt>"String"</tt> or <tt>:Symbol</tt>
@@ -41,6 +32,7 @@ module RubyXL
41
32
  # * +:accessor+ - Name of the accessor for this attribute to be defined on the object. If not provided, defaults to classidied +attribute_name+.
42
33
  # * +:default+ - Value this attribute defaults to if not explicitly provided.
43
34
  # * +:required+ - Whether this attribute is required when writing XML. If the value of the attrinute is not explicitly provided, +:default+ is written instead.
35
+ # * +:computed+ - Do not store this attribute on +parse+, but do call the object-provided read accessor on +write_xml+.
44
36
  # ==== Examples
45
37
  # define_attribute(:outline, :bool, :default => true)
46
38
  # A <tt>Boolean</tt> attribute 'outline' with default value +true+ will be accessible by calling +obj.outline+
@@ -48,32 +40,16 @@ module RubyXL
48
40
  # An <tt>Integer</tt> attribute 'uniqueCount' accessible as +obj.unique_count+
49
41
  # define_attribute(:_, :string, :accessor => :expression)
50
42
  # The value of the element will be accessible as a <tt>String</tt> by calling +obj.expression+
51
- # define_attribute(:errorStyle, :string, :default => 'stop', :values => %w{ stop warning information })
43
+ # define_attribute(:errorStyle, %w{ stop warning information }, :default => 'stop',)
52
44
  # A <tt>String</tt> attribute named 'errorStyle' will be accessible as +obj.error_style+, valid values are <tt>"stop"</tt>, <tt>"warning"</tt>, <tt>"information"</tt>
53
- def self.define_attribute(attr_name, attr_type, extra_params = {})
45
+ def define_attribute(attr_name, attr_type, extra_params = {})
54
46
  attrs = obtain_class_variable(:@@ooxml_attributes)
55
-
56
- accessor = extra_params[:accessor] || accessorize(attr_name)
57
- attr_name = attr_name.to_s
58
-
59
- attr_hash = {
60
- :accessor => accessor,
61
- :attr_type => attr_type,
62
- :optional => !extra_params[:required],
63
- :default => extra_params[:default],
64
- }
65
-
66
- if attr_type.is_a?(Array) then
67
- attr_hash[:values] = attr_type
68
- attr_hash[:attr_type] = :string
69
- end
70
-
71
-
72
- attrs[attr_name] = attr_hash
73
-
74
- self.send(:attr_accessor, accessor)
47
+ attr_hash = extra_params.merge({ :attr_type => attr_type })
48
+ attr_hash[:accessor] ||= accessorize(attr_name)
49
+ attrs[attr_name.to_s] = attr_hash
50
+ self.send(:attr_accessor, attr_hash[:accessor]) unless attr_hash[:computed]
75
51
  end
76
-
52
+
77
53
  # Defines a child node of OOXML object.
78
54
  # === Parameters
79
55
  # * +klass+ - Class (descendant of RubyXL::OOXMLObject) of the child nodes. Child node objects will be produced by calling +parse+ method of that class.
@@ -94,7 +70,7 @@ module RubyXL
94
70
  # Use class RubyXL::BorderEdge when parsing both the elements <tt><left ...></tt> and <tt><right ...></tt> elements.
95
71
  # define_child_node(RubyXL::Font, :collection => :with_count, :accessor => :fonts)
96
72
  # Upon writing of the object this was defined on, its <tt>count</tt> attribute will be set to the count of nodes in <tt>fonts</tt> array
97
- def self.define_child_node(klass, extra_params = {})
73
+ def define_child_node(klass, extra_params = {})
98
74
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
99
75
  child_node_name = (extra_params[:node_name] || klass.class_variable_get(:@@ooxml_tag_name)).to_s
100
76
  accessor = (extra_params[:accessor] || accessorize(child_node_name)).to_sym
@@ -105,13 +81,16 @@ module RubyXL
105
81
  :accessor => accessor
106
82
  }
107
83
 
108
- if extra_params[:collection] == :with_count then
109
- define_attribute(:count, :int, :required => true)
110
- end
84
+ define_count_attribute if extra_params[:collection] == :with_count
111
85
 
112
86
  self.send(:attr_accessor, accessor)
113
87
  end
114
88
 
89
+ def define_count_attribute
90
+ define_attribute(:count, :int, :required => true)
91
+ end
92
+ private :define_count_attribute
93
+
115
94
  # Defines the name of the element that represents the current OOXML object. Should only be used once per object.
116
95
  # In case of different objects represented by the same class in different parts of OOXML tree, +:node_name+
117
96
  # extra parameter can be used to override the default element name.
@@ -119,92 +98,17 @@ module RubyXL
119
98
  # * +element_name+
120
99
  # ==== Examples
121
100
  # define_element_name 'externalReference'
122
- def self.define_element_name(element_name)
101
+ def define_element_name(element_name)
123
102
  self.class_variable_set(:@@ooxml_tag_name, element_name)
124
103
  end
125
104
 
126
105
  # #TODO# This method will eventually be obsoleted.
127
- def self.set_countable
106
+ def set_countable
128
107
  self.class_variable_set(:@@ooxml_countable, true)
129
108
  self.send(:attr_accessor, :count)
130
109
  end
131
110
 
132
- # Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual
133
- # generation, +before_write_xml()+ is called to perform last-minute cleanup and validation operations; if it
134
- # returns +false+, an empty string is returned (rather than +nil+, so Nokogiri::XML's <tt>&lt;&lt;</tt> operator
135
- # can be used without additional +nil+ checking)
136
- # === Parameters
137
- # * +xml+ - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.
138
- # * +node_name_override+ - if present, is used instead of the default element name for this object provided by +define_element_name+
139
- # ==== Examples
140
- # obj.write_xml
141
- # Creates a new Nokogiti::XML and
142
- def write_xml(xml = nil, node_name_override = nil)
143
- if xml.nil? then
144
- seed_xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
145
- seed_xml.encoding = 'UTF-8'
146
- result = self.write_xml(seed_xml)
147
- return result if result == ''
148
- seed_xml << result
149
- return seed_xml.to_xml({ :indent => 0, :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML })
150
- end
151
-
152
- return '' unless before_write_xml
153
-
154
- attrs = obtain_class_variable(:@@ooxml_namespaces).dup
155
-
156
- obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|
157
- val = self.send(v[:accessor])
158
-
159
- if val.nil? then
160
- next if v[:optional]
161
- val = v[:default]
162
- end
163
-
164
- val = val &&
165
- case v[:attr_type]
166
- when :bool then val ? '1' : '0'
167
- when :float then val.to_s.gsub(/\.0*$/, '') # Trim trailing zeroes
168
- else val
169
- end
170
-
171
- attrs[k] = val
172
- }
173
-
174
- element_text = attrs.delete('_')
175
- elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)
176
- child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
177
- child_nodes.each_pair { |child_node_name, child_node_params|
178
- obj = self.send(child_node_params[:accessor])
179
- unless obj.nil?
180
- if child_node_params[:is_array] then obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
181
- else elem << obj.write_xml(xml, child_node_name)
182
- end
183
- end
184
- }
185
- elem
186
- end
187
-
188
- def initialize(params = {})
189
- obtain_class_variable(:@@ooxml_attributes).each_value { |v|
190
- instance_variable_set("@#{v[:accessor]}", params[v[:accessor]])
191
- }
192
-
193
- obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
194
-
195
- initial_value =
196
- if params.has_key?(v[:accessor]) then params[v[:accessor]]
197
- elsif v[:is_array] then []
198
- else nil
199
- end
200
-
201
- instance_variable_set("@#{v[:accessor]}", initial_value)
202
- }
203
-
204
- instance_variable_set("@count", 0) if obtain_class_variable(:@@ooxml_countable, false)
205
- end
206
-
207
- def self.parse(node)
111
+ def parse(node)
208
112
  node = Nokogiri::XML.parse(node) if node.is_a?(IO) || node.is_a?(String)
209
113
 
210
114
  if node.is_a?(Nokogiri::XML::Document) then
@@ -230,7 +134,7 @@ module RubyXL
230
134
 
231
135
  next if attr_params.nil?
232
136
  # raise "Unknown attribute: #{attr_name}" if attr_params.nil?
233
- process_attribute(obj, attr.value, attr_params)
137
+ process_attribute(obj, attr.value, attr_params) unless attr_params[:computed]
234
138
  }
235
139
 
236
140
  known_child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
@@ -248,7 +152,11 @@ module RubyXL
248
152
  parsed_object = child_node_params[:class].parse(child_node)
249
153
  if child_node_params[:is_array] then
250
154
  index = parsed_object.index_in_collection
251
- collection = obj.send(child_node_params[:accessor])
155
+
156
+ collection = if (self < RubyXL::OOXMLContainerObject) then obj
157
+ else obj.send(child_node_params[:accessor])
158
+ end
159
+
252
160
  if index.nil? then
253
161
  collection << parsed_object
254
162
  else
@@ -263,6 +171,126 @@ module RubyXL
263
171
  obj
264
172
  end
265
173
 
174
+ private
175
+ def accessorize(str)
176
+ acc = str.to_s.dup
177
+ acc.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
178
+ acc.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
179
+ acc.gsub!(':','_')
180
+ acc.downcase.to_sym
181
+ end
182
+
183
+ def process_attribute(obj, raw_value, params)
184
+ val = raw_value &&
185
+ case params[:attr_type]
186
+ when :int then Integer(raw_value)
187
+ when :float then Float(raw_value)
188
+ when :string then raw_value
189
+ when Array then raw_value # Case of Simple Types
190
+ when :sqref then RubyXL::Sqref.new(raw_value)
191
+ when :ref then RubyXL::Reference.new(raw_value)
192
+ when :bool then ['1', 'true'].include?(raw_value)
193
+ end
194
+ obj.send("#{params[:accessor]}=", val)
195
+ end
196
+
197
+ end
198
+
199
+
200
+ module OOXMLObjectInstanceMethods
201
+
202
+ def obtain_class_variable(var_name, default = {})
203
+ self.class.obtain_class_variable(var_name, default)
204
+ end
205
+ private :obtain_class_variable
206
+
207
+ def initialize(params = {})
208
+ obtain_class_variable(:@@ooxml_attributes).each_value { |v|
209
+ instance_variable_set("@#{v[:accessor]}", params[v[:accessor]]) unless v[:computed]
210
+ }
211
+
212
+ init_child_nodes(params)
213
+
214
+ instance_variable_set("@count", 0) if obtain_class_variable(:@@ooxml_countable, false)
215
+ end
216
+
217
+ def init_child_nodes(params)
218
+ obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
219
+
220
+ initial_value =
221
+ if params.has_key?(v[:accessor]) then params[v[:accessor]]
222
+ elsif v[:is_array] then []
223
+ else nil
224
+ end
225
+
226
+ instance_variable_set("@#{v[:accessor]}", initial_value)
227
+ }
228
+ end
229
+ private :init_child_nodes
230
+
231
+ # Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual
232
+ # generation, +before_write_xml()+ is called to perform last-minute cleanup and validation operations; if it
233
+ # returns +false+, an empty string is returned (rather than +nil+, so Nokogiri::XML's <tt>&lt;&lt;</tt> operator
234
+ # can be used without additional +nil+ checking)
235
+ # === Parameters
236
+ # * +xml+ - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.
237
+ # * +node_name_override+ - if present, is used instead of the default element name for this object provided by +define_element_name+
238
+ # ==== Examples
239
+ # obj.write_xml
240
+ # Creates a new Nokogiti::XML and
241
+ def write_xml(xml = nil, node_name_override = nil)
242
+ if xml.nil? then
243
+ seed_xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
244
+ seed_xml.encoding = 'UTF-8'
245
+ result = self.write_xml(seed_xml)
246
+ return result if result == ''
247
+ seed_xml << result
248
+ return seed_xml.to_xml({ :indent => 0, :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML })
249
+ end
250
+
251
+ return '' unless before_write_xml
252
+
253
+ attrs = obtain_class_variable(:@@ooxml_namespaces).dup
254
+
255
+ obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|
256
+ val = self.send(v[:accessor])
257
+
258
+ if val.nil? then
259
+ next unless v[:required]
260
+ val = v[:default]
261
+ end
262
+
263
+ val = val &&
264
+ case v[:attr_type]
265
+ when :bool then val ? '1' : '0'
266
+ when :float then val.to_s.gsub(/\.0*$/, '') # Trim trailing zeroes
267
+ else val
268
+ end
269
+
270
+ attrs[k] = val
271
+ }
272
+
273
+ element_text = attrs.delete('_')
274
+ elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)
275
+
276
+ child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
277
+ child_nodes.each_pair { |child_node_name, child_node_params|
278
+ node_obj = get_node_object(child_node_params)
279
+ next if node_obj.nil?
280
+
281
+ if node_obj.respond_to?(:write_xml) && !node_obj.equal?(self) then
282
+ # If child node is either +OOXMLObject+, or +OOXMLContainerObject+ on its first (envelope) pass,
283
+ # serialize that object.
284
+ elem << node_obj.write_xml(xml, child_node_name)
285
+ else
286
+ # If child node is either vanilla +Array+, or +OOXMLContainerObject+ on its seconds (content) pass,
287
+ # serialize write its members.
288
+ node_obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
289
+ end
290
+ }
291
+ elem
292
+ end
293
+
266
294
  def dup
267
295
  new_copy = super
268
296
  new_copy.count = 0 if obtain_class_variable(:@@ooxml_countable, false)
@@ -276,10 +304,16 @@ module RubyXL
276
304
  nil
277
305
  end
278
306
 
307
+ def get_node_object(child_node_params)
308
+ self.send(child_node_params[:accessor])
309
+ end
310
+ private :get_node_object
311
+
279
312
  # Subclass provided filter to perform last-minute operations (cleanup, count, etc.) immediately prior to write,
280
313
  # along with option to terminate the actual write if +false+ is returned (for example, to avoid writing
281
314
  # the collection's root node if the collection is empty).
282
315
  def before_write_xml
316
+ #TODO# This will go away once containers are fully implemented.
283
317
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
284
318
  child_nodes.each_pair { |child_node_name, child_node_params|
285
319
  self.count = self.send(child_node_params[:accessor]).size if child_node_params[:is_array] == :with_count
@@ -287,36 +321,73 @@ module RubyXL
287
321
  true
288
322
  end
289
323
 
290
- private
291
- def self.accessorize(str)
292
- acc = str.to_s.dup
293
- acc.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
294
- acc.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
295
- acc.gsub!(':','_')
296
- acc.downcase.to_sym
324
+ end
325
+
326
+ # Parent class for defining OOXML based objects (not unlike Rails' +ActiveRecord+!)
327
+ # Most importantly, provides functionality of parsing such objects from XML,
328
+ # and marshalling them to XML.
329
+ class OOXMLObject
330
+ include OOXMLObjectInstanceMethods
331
+ extend OOXMLObjectClassMethods
332
+ end
333
+
334
+ # Parent class for OOXML conainer objects (for example,
335
+ # <tt>&lt;fonts&gt;&lt;font&gt;...&lt;/font&gt;&lt;font&gt;...&lt;/font&gt;&lt;/fonts&gt;</tt>
336
+ # that obscures the top-level container, allowing direct access to the contents as +Array+.
337
+ class OOXMLContainerObject < Array
338
+ include OOXMLObjectInstanceMethods
339
+ extend OOXMLObjectClassMethods
340
+
341
+ def initialize(params = {})
342
+ array_content = params.delete(:_)
343
+ super
344
+ array_content.each_with_index { |v, i| self[i] = v } if array_content
297
345
  end
298
346
 
299
- def self.process_attribute(obj, raw_value, params)
300
- val = raw_value &&
301
- case params[:attr_type]
302
- when :int then Integer(raw_value)
303
- when :float then Float(raw_value)
304
- when :string then raw_value
305
- when :sqref then RubyXL::Sqref.new(raw_value)
306
- when :ref then RubyXL::Reference.new(raw_value)
307
- when :bool then ['1', 'true'].include?(raw_value)
308
- end
309
- obj.send("#{params[:accessor]}=", val)
347
+ def get_node_object(child_node_params)
348
+ if child_node_params[:is_array] then self
349
+ else super
350
+ end
351
+ end
352
+ protected :get_node_object
353
+
354
+ def init_child_nodes(params)
355
+ obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
356
+ next if v[:is_array] # Only one collection node allowed per OOXMLContainerObject, and it is contained in itself.
357
+ instance_variable_set("@#{v[:accessor]}", params[v[:accessor]])
358
+ }
359
+ end
360
+ protected :init_child_nodes
361
+
362
+ def before_write_xml
363
+ true
364
+ end
365
+
366
+ def inspect
367
+ vars = [ super ]
368
+ vars = self.instance_variables.each { |v| vars << "#{v}=#{instance_variable_get(v).inspect}" }
369
+ "<#{self.class}: #{super} #{vars.join(", ")}>"
370
+ end
371
+
372
+ class << self
373
+ def define_count_attribute
374
+ # Count will be inherited from Array. so no need to define it explicitly.
375
+ define_attribute(:count, :int, :required => true, :computed => true)
376
+ end
377
+ protected :define_count_attribute
310
378
  end
311
379
 
312
380
  end
313
381
 
314
382
  # Extension class providing functionality for top-level OOXML objects that are represented by
315
383
  # their own <tt>.xml</tt> files in <tt>.xslx</tt> zip container.
316
-
317
384
  class OOXMLTopLevelObject < OOXMLObject
318
385
  # Prototype method. For top-level OOXML object, returns the path at which the current object's XML file
319
386
  # is located within the <tt>.xslx</tt> zip container.
387
+ def filepath
388
+ self.class.filepath
389
+ end
390
+
320
391
  def self.filepath
321
392
  raise 'Subclass responsebility'
322
393
  end
@@ -347,7 +418,7 @@ module RubyXL
347
418
  def add_to_zip(zipfile)
348
419
  xml_string = write_xml
349
420
  return if xml_string.empty?
350
- zipfile.get_output_stream(self.class.filepath) { |f| f << xml_string }
421
+ zipfile.get_output_stream(self.filepath) { |f| f << xml_string }
351
422
  end
352
423
 
353
424
  end