rubyXL 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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