rubyXL 3.2.0 → 3.2.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 (379) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +2 -1
  3. data/VERSION +1 -1
  4. data/lib/rubyXL.rb +6 -1
  5. data/lib/rubyXL/objects/border.rb +13 -31
  6. data/lib/rubyXL/objects/calculation_chain.rb +31 -31
  7. data/lib/rubyXL/objects/cell_style.rb +65 -79
  8. data/lib/rubyXL/objects/chartsheet.rb +85 -85
  9. data/lib/rubyXL/objects/column_range.rb +40 -40
  10. data/lib/rubyXL/objects/comments.rb +21 -21
  11. data/lib/rubyXL/objects/content_types.rb +69 -78
  12. data/lib/rubyXL/objects/data_validation.rb +37 -37
  13. data/lib/rubyXL/objects/document_properties.rb +157 -157
  14. data/lib/rubyXL/objects/extensions.rb +17 -17
  15. data/lib/rubyXL/objects/fill.rb +48 -48
  16. data/lib/rubyXL/objects/filters.rb +119 -119
  17. data/lib/rubyXL/objects/font.rb +0 -10
  18. data/lib/rubyXL/objects/formula.rb +24 -24
  19. data/lib/rubyXL/objects/ooxml_object.rb +443 -456
  20. data/lib/rubyXL/objects/reference.rb +110 -110
  21. data/lib/rubyXL/objects/relationships.rb +3 -10
  22. data/lib/rubyXL/objects/root.rb +81 -81
  23. data/lib/rubyXL/objects/shared_strings.rb +60 -60
  24. data/lib/rubyXL/objects/sheet_common.rb +51 -51
  25. data/lib/rubyXL/objects/sheet_data.rb +173 -173
  26. data/lib/rubyXL/objects/simple_types.rb +229 -229
  27. data/lib/rubyXL/objects/storage.rb +141 -158
  28. data/lib/rubyXL/objects/stylesheet.rb +57 -57
  29. data/lib/rubyXL/objects/text.rb +87 -87
  30. data/lib/rubyXL/objects/theme.rb +21 -21
  31. data/lib/rubyXL/objects/workbook.rb +3 -3
  32. data/lib/rubyXL/objects/worksheet.rb +724 -723
  33. data/lib/rubyXL/parser.rb +0 -1
  34. data/lib/rubyXL/workbook.rb +1 -2
  35. data/rdoc/README_rdoc.html +6 -3
  36. data/rdoc/RubyXL.html +53 -1
  37. data/rdoc/RubyXL/AExtension.html +1 -1
  38. data/rdoc/RubyXL/AExtensionStorageArea.html +1 -1
  39. data/rdoc/RubyXL/AdjustHandleList.html +1 -1
  40. data/rdoc/RubyXL/Alignment.html +1 -1
  41. data/rdoc/RubyXL/AlternateContent.html +1 -1
  42. data/rdoc/RubyXL/Authors.html +1 -1
  43. data/rdoc/RubyXL/AutoFilter.html +1 -1
  44. data/rdoc/RubyXL/AutoFilterColumn.html +1 -1
  45. data/rdoc/RubyXL/BinaryImageFile.html +1 -1
  46. data/rdoc/RubyXL/BodyProperties.html +1 -1
  47. data/rdoc/RubyXL/BooleanNode.html +1 -1
  48. data/rdoc/RubyXL/BooleanValue.html +1 -1
  49. data/rdoc/RubyXL/Border.html +1 -1
  50. data/rdoc/RubyXL/BorderEdge.html +1 -52
  51. data/rdoc/RubyXL/Borders.html +1 -1
  52. data/rdoc/RubyXL/Break.html +1 -1
  53. data/rdoc/RubyXL/BreakList.html +1 -1
  54. data/rdoc/RubyXL/CT_AdjPoint2D.html +1 -1
  55. data/rdoc/RubyXL/CT_AlphaBiLevelEffect.html +1 -1
  56. data/rdoc/RubyXL/CT_AlphaModulateEffect.html +1 -1
  57. data/rdoc/RubyXL/CT_AlphaModulateFixedEffect.html +1 -1
  58. data/rdoc/RubyXL/CT_AlphaOutsetEffect.html +1 -1
  59. data/rdoc/RubyXL/CT_AlphaReplaceEffect.html +1 -1
  60. data/rdoc/RubyXL/CT_Backdrop.html +1 -1
  61. data/rdoc/RubyXL/CT_Bevel.html +1 -1
  62. data/rdoc/RubyXL/CT_BiLevelEffect.html +1 -1
  63. data/rdoc/RubyXL/CT_BlendEffect.html +1 -1
  64. data/rdoc/RubyXL/CT_Blip.html +1 -1
  65. data/rdoc/RubyXL/CT_BlipFillProperties.html +1 -1
  66. data/rdoc/RubyXL/CT_BlurEffect.html +1 -1
  67. data/rdoc/RubyXL/CT_Camera.html +1 -1
  68. data/rdoc/RubyXL/CT_Color.html +1 -1
  69. data/rdoc/RubyXL/CT_ColorChangeEffect.html +1 -1
  70. data/rdoc/RubyXL/CT_ColorMapping.html +1 -1
  71. data/rdoc/RubyXL/CT_ColorScheme.html +1 -1
  72. data/rdoc/RubyXL/CT_ColorSchemeAndMapping.html +1 -1
  73. data/rdoc/RubyXL/CT_ConnectionSite.html +1 -1
  74. data/rdoc/RubyXL/CT_ConnectionSiteList.html +1 -1
  75. data/rdoc/RubyXL/CT_DashStop.html +1 -1
  76. data/rdoc/RubyXL/CT_DashStopList.html +1 -1
  77. data/rdoc/RubyXL/CT_DefaultShapeDefinition.html +1 -1
  78. data/rdoc/RubyXL/CT_DuotoneEffect.html +1 -1
  79. data/rdoc/RubyXL/CT_EffectContainer.html +1 -1
  80. data/rdoc/RubyXL/CT_EffectList.html +1 -1
  81. data/rdoc/RubyXL/CT_EffectReference.html +1 -1
  82. data/rdoc/RubyXL/CT_EffectStyleItem.html +1 -1
  83. data/rdoc/RubyXL/CT_EffectStyleList.html +1 -1
  84. data/rdoc/RubyXL/CT_EmbeddedWAVAudioFile.html +1 -1
  85. data/rdoc/RubyXL/CT_FillEffect.html +1 -1
  86. data/rdoc/RubyXL/CT_FillOverlayEffect.html +1 -1
  87. data/rdoc/RubyXL/CT_FillStyleList.html +1 -1
  88. data/rdoc/RubyXL/CT_FlatText.html +1 -1
  89. data/rdoc/RubyXL/CT_FontCollection.html +1 -1
  90. data/rdoc/RubyXL/CT_FontReference.html +1 -1
  91. data/rdoc/RubyXL/CT_GeomGuideList.html +1 -1
  92. data/rdoc/RubyXL/CT_GlowEffect.html +1 -1
  93. data/rdoc/RubyXL/CT_GradientFillProperties.html +1 -1
  94. data/rdoc/RubyXL/CT_GradientStop.html +1 -1
  95. data/rdoc/RubyXL/CT_GradientStopList.html +1 -1
  96. data/rdoc/RubyXL/CT_HSLEffect.html +1 -1
  97. data/rdoc/RubyXL/CT_HslColor.html +1 -1
  98. data/rdoc/RubyXL/CT_Hyperlink.html +1 -1
  99. data/rdoc/RubyXL/CT_InnerShadowEffect.html +1 -1
  100. data/rdoc/RubyXL/CT_LightRig.html +1 -1
  101. data/rdoc/RubyXL/CT_LineEndProperties.html +1 -1
  102. data/rdoc/RubyXL/CT_LineJoinMiterProperties.html +1 -1
  103. data/rdoc/RubyXL/CT_LineProperties.html +1 -1
  104. data/rdoc/RubyXL/CT_LineStyleList.html +1 -1
  105. data/rdoc/RubyXL/CT_LinearShadeProperties.html +1 -1
  106. data/rdoc/RubyXL/CT_LuminanceEffect.html +1 -1
  107. data/rdoc/RubyXL/CT_ObjectStyleDefaults.html +1 -1
  108. data/rdoc/RubyXL/CT_OuterShadowEffect.html +1 -1
  109. data/rdoc/RubyXL/CT_Path2D.html +1 -1
  110. data/rdoc/RubyXL/CT_Path2DArcTo.html +1 -1
  111. data/rdoc/RubyXL/CT_Path2DCubicBezierTo.html +1 -1
  112. data/rdoc/RubyXL/CT_Path2DList.html +1 -1
  113. data/rdoc/RubyXL/CT_Path2DQuadBezierTo.html +1 -1
  114. data/rdoc/RubyXL/CT_Path2DTo.html +1 -1
  115. data/rdoc/RubyXL/CT_PathShadeProperties.html +1 -1
  116. data/rdoc/RubyXL/CT_PatternFillProperties.html +1 -1
  117. data/rdoc/RubyXL/CT_Point3D.html +1 -1
  118. data/rdoc/RubyXL/CT_PolarAdjustHandle.html +1 -1
  119. data/rdoc/RubyXL/CT_PresetColor.html +1 -1
  120. data/rdoc/RubyXL/CT_PresetLineDashProperties.html +1 -1
  121. data/rdoc/RubyXL/CT_PresetShadowEffect.html +1 -1
  122. data/rdoc/RubyXL/CT_PresetTextShape.html +1 -1
  123. data/rdoc/RubyXL/CT_ReflectionEffect.html +1 -1
  124. data/rdoc/RubyXL/CT_RelativeOffsetEffect.html +1 -1
  125. data/rdoc/RubyXL/CT_RelativeRect.html +1 -1
  126. data/rdoc/RubyXL/CT_SRgbColor.html +1 -1
  127. data/rdoc/RubyXL/CT_ScRgbColor.html +1 -1
  128. data/rdoc/RubyXL/CT_Scene3D.html +1 -1
  129. data/rdoc/RubyXL/CT_SchemeColor.html +1 -1
  130. data/rdoc/RubyXL/CT_Shape3D.html +1 -1
  131. data/rdoc/RubyXL/CT_ShapeStyle.html +1 -1
  132. data/rdoc/RubyXL/CT_SoftEdgesEffect.html +1 -1
  133. data/rdoc/RubyXL/CT_SphereCoords.html +1 -1
  134. data/rdoc/RubyXL/CT_StretchInfoProperties.html +1 -1
  135. data/rdoc/RubyXL/CT_StyleMatrix.html +1 -1
  136. data/rdoc/RubyXL/CT_StyleMatrixReference.html +1 -1
  137. data/rdoc/RubyXL/CT_SupplementalFont.html +1 -1
  138. data/rdoc/RubyXL/CT_SystemColor.html +1 -1
  139. data/rdoc/RubyXL/CT_TextAutonumberBullet.html +1 -1
  140. data/rdoc/RubyXL/CT_TextBlipBullet.html +1 -1
  141. data/rdoc/RubyXL/CT_TextCharBullet.html +1 -1
  142. data/rdoc/RubyXL/CT_TextCharacterProperties.html +1 -1
  143. data/rdoc/RubyXL/CT_TextFont.html +1 -1
  144. data/rdoc/RubyXL/CT_TextListStyle.html +1 -1
  145. data/rdoc/RubyXL/CT_TextNormalAutofit.html +1 -1
  146. data/rdoc/RubyXL/CT_TextParagraphProperties.html +1 -1
  147. data/rdoc/RubyXL/CT_TextSpacing.html +1 -1
  148. data/rdoc/RubyXL/CT_TextTabStop.html +1 -1
  149. data/rdoc/RubyXL/CT_TextTabStopList.html +1 -1
  150. data/rdoc/RubyXL/CT_TileInfoProperties.html +1 -1
  151. data/rdoc/RubyXL/CT_TintEffect.html +1 -1
  152. data/rdoc/RubyXL/CT_Transform2D.html +1 -1
  153. data/rdoc/RubyXL/CT_TransformEffect.html +1 -1
  154. data/rdoc/RubyXL/CT_Vector3D.html +1 -1
  155. data/rdoc/RubyXL/CT_XYAdjustHandle.html +1 -1
  156. data/rdoc/RubyXL/CalculationChain.html +3 -3
  157. data/rdoc/RubyXL/CalculationChainCell.html +1 -1
  158. data/rdoc/RubyXL/CalculationProperties.html +1 -1
  159. data/rdoc/RubyXL/Cell.html +36 -36
  160. data/rdoc/RubyXL/CellSmartTag.html +1 -1
  161. data/rdoc/RubyXL/CellSmartTagProperty.html +1 -1
  162. data/rdoc/RubyXL/CellSmartTags.html +1 -1
  163. data/rdoc/RubyXL/CellStyle.html +1 -1
  164. data/rdoc/RubyXL/CellStyleXFs.html +1 -1
  165. data/rdoc/RubyXL/CellStyles.html +1 -1
  166. data/rdoc/RubyXL/CellValue.html +4 -4
  167. data/rdoc/RubyXL/CellWatch.html +1 -1
  168. data/rdoc/RubyXL/CellWatches.html +1 -1
  169. data/rdoc/RubyXL/CellXFs.html +1 -1
  170. data/rdoc/RubyXL/ChartColorsFile.html +1 -1
  171. data/rdoc/RubyXL/ChartFile.html +1 -1
  172. data/rdoc/RubyXL/ChartStyleFile.html +1 -1
  173. data/rdoc/RubyXL/ChartUserShapesFile.html +1 -1
  174. data/rdoc/RubyXL/Chartsheet.html +1 -1
  175. data/rdoc/RubyXL/ChartsheetPageSetup.html +1 -1
  176. data/rdoc/RubyXL/ChartsheetProperties.html +1 -1
  177. data/rdoc/RubyXL/ChartsheetProtection.html +1 -1
  178. data/rdoc/RubyXL/ChartsheetView.html +1 -1
  179. data/rdoc/RubyXL/ChartsheetViews.html +1 -1
  180. data/rdoc/RubyXL/Color.html +1 -1
  181. data/rdoc/RubyXL/ColorFilter.html +1 -1
  182. data/rdoc/RubyXL/ColorScale.html +1 -1
  183. data/rdoc/RubyXL/ColorSet.html +1 -1
  184. data/rdoc/RubyXL/Colors.html +1 -1
  185. data/rdoc/RubyXL/ColumnRange.html +1 -1
  186. data/rdoc/RubyXL/ColumnRanges.html +22 -22
  187. data/rdoc/RubyXL/Comment.html +1 -1
  188. data/rdoc/RubyXL/CommentList.html +1 -1
  189. data/rdoc/RubyXL/CommentsFile.html +1 -1
  190. data/rdoc/RubyXL/ConditionalFormatValue.html +1 -1
  191. data/rdoc/RubyXL/ConditionalFormatting.html +1 -1
  192. data/rdoc/RubyXL/ConditionalFormattingRule.html +1 -1
  193. data/rdoc/RubyXL/ContentTypeDefault.html +1 -1
  194. data/rdoc/RubyXL/ContentTypeOverride.html +1 -1
  195. data/rdoc/RubyXL/ContentTypes.html +47 -91
  196. data/rdoc/RubyXL/ControlPropertiesFile.html +1 -1
  197. data/rdoc/RubyXL/CorePropertiesFile.html +1 -1
  198. data/rdoc/RubyXL/CustomColor.html +1 -1
  199. data/rdoc/RubyXL/CustomColorList.html +1 -1
  200. data/rdoc/RubyXL/CustomFilter.html +1 -1
  201. data/rdoc/RubyXL/CustomFilters.html +1 -1
  202. data/rdoc/RubyXL/CustomGeometry.html +1 -1
  203. data/rdoc/RubyXL/CustomProperties.html +1 -1
  204. data/rdoc/RubyXL/CustomPropertiesFile.html +1 -1
  205. data/rdoc/RubyXL/CustomProperty.html +1 -1
  206. data/rdoc/RubyXL/CustomSheetView.html +1 -1
  207. data/rdoc/RubyXL/CustomSheetViews.html +1 -1
  208. data/rdoc/RubyXL/CustomWorkbookView.html +1 -1
  209. data/rdoc/RubyXL/CustomWorkbookViews.html +1 -1
  210. data/rdoc/RubyXL/CustomXMLFile.html +1 -1
  211. data/rdoc/RubyXL/DXF.html +1 -1
  212. data/rdoc/RubyXL/DXFs.html +1 -1
  213. data/rdoc/RubyXL/DataBar.html +1 -1
  214. data/rdoc/RubyXL/DataConsolidate.html +1 -1
  215. data/rdoc/RubyXL/DataConsolidationReference.html +1 -1
  216. data/rdoc/RubyXL/DataConsolidationReferences.html +1 -1
  217. data/rdoc/RubyXL/DataType.html +1 -1
  218. data/rdoc/RubyXL/DataValidation.html +1 -1
  219. data/rdoc/RubyXL/DataValidations.html +2 -2
  220. data/rdoc/RubyXL/DateGroupItem.html +1 -1
  221. data/rdoc/RubyXL/DefinedName.html +1 -1
  222. data/rdoc/RubyXL/DefinedNames.html +1 -1
  223. data/rdoc/RubyXL/DocumentPropertiesFile.html +28 -28
  224. data/rdoc/RubyXL/DrawingFile.html +1 -86
  225. data/rdoc/RubyXL/DynamicFilter.html +1 -1
  226. data/rdoc/RubyXL/EmbeddedControl.html +1 -1
  227. data/rdoc/RubyXL/EmbeddedControls.html +1 -1
  228. data/rdoc/RubyXL/Extension.html +1 -1
  229. data/rdoc/RubyXL/ExtensionStorageArea.html +1 -1
  230. data/rdoc/RubyXL/Extents.html +1 -1
  231. data/rdoc/RubyXL/ExternalLinksFile.html +1 -1
  232. data/rdoc/RubyXL/ExternalReference.html +1 -1
  233. data/rdoc/RubyXL/ExternalReferences.html +1 -1
  234. data/rdoc/RubyXL/ExtraColorSchemeList.html +1 -1
  235. data/rdoc/RubyXL/FieldItem.html +1 -1
  236. data/rdoc/RubyXL/FileRecoveryProperties.html +1 -1
  237. data/rdoc/RubyXL/FileSharing.html +1 -1
  238. data/rdoc/RubyXL/FileVersion.html +1 -1
  239. data/rdoc/RubyXL/Fill.html +1 -1
  240. data/rdoc/RubyXL/Fills.html +1 -1
  241. data/rdoc/RubyXL/FilterContainer.html +1 -1
  242. data/rdoc/RubyXL/FloatNode.html +1 -1
  243. data/rdoc/RubyXL/FloatValue.html +1 -1
  244. data/rdoc/RubyXL/Font.html +15 -56
  245. data/rdoc/RubyXL/FontScheme.html +1 -1
  246. data/rdoc/RubyXL/Fonts.html +1 -1
  247. data/rdoc/RubyXL/Formula.html +1 -1
  248. data/rdoc/RubyXL/FunctionGroup.html +1 -1
  249. data/rdoc/RubyXL/FunctionGroups.html +1 -1
  250. data/rdoc/RubyXL/GenericStorageObject.html +14 -31
  251. data/rdoc/RubyXL/GradientFill.html +1 -1
  252. data/rdoc/RubyXL/HeaderFooterSettings.html +1 -1
  253. data/rdoc/RubyXL/Hyperlink.html +1 -1
  254. data/rdoc/RubyXL/HyperlinkRelFile.html +1 -1
  255. data/rdoc/RubyXL/Hyperlinks.html +1 -1
  256. data/rdoc/RubyXL/IconFilter.html +1 -1
  257. data/rdoc/RubyXL/IconSet.html +1 -1
  258. data/rdoc/RubyXL/IgnoredError.html +1 -1
  259. data/rdoc/RubyXL/IgnoredErrors.html +1 -1
  260. data/rdoc/RubyXL/IndexedColors.html +1 -1
  261. data/rdoc/RubyXL/InputCells.html +1 -1
  262. data/rdoc/RubyXL/IntegerNode.html +1 -1
  263. data/rdoc/RubyXL/IntegerValue.html +1 -1
  264. data/rdoc/RubyXL/LegacyCell.html +1 -1
  265. data/rdoc/RubyXL/LegacyWorkbook.html +22 -22
  266. data/rdoc/RubyXL/LegacyWorksheet.html +1 -1
  267. data/rdoc/RubyXL/MRUColors.html +1 -1
  268. data/rdoc/RubyXL/MacrosFile.html +1 -1
  269. data/rdoc/RubyXL/MergedCell.html +1 -1
  270. data/rdoc/RubyXL/MergedCells.html +1 -1
  271. data/rdoc/RubyXL/NumFmt.html +1 -1
  272. data/rdoc/RubyXL/NumberFormat.html +2 -2
  273. data/rdoc/RubyXL/NumberFormats.html +1 -1
  274. data/rdoc/RubyXL/OLEObject.html +1 -1
  275. data/rdoc/RubyXL/OLEObjects.html +1 -1
  276. data/rdoc/RubyXL/OLESize.html +1 -1
  277. data/rdoc/RubyXL/OOXMLContainerObject.html +1 -1
  278. data/rdoc/RubyXL/OOXMLObject.html +1 -1
  279. data/rdoc/RubyXL/OOXMLObjectClassMethods.html +99 -99
  280. data/rdoc/RubyXL/OOXMLObjectInstanceMethods.html +1 -1
  281. data/rdoc/RubyXL/OOXMLRelationshipsFile.html +12 -19
  282. data/rdoc/RubyXL/OOXMLTopLevelObject.html +1 -1
  283. data/rdoc/RubyXL/Offset.html +1 -1
  284. data/rdoc/RubyXL/OutlineProperties.html +1 -1
  285. data/rdoc/RubyXL/PageMargins.html +1 -1
  286. data/rdoc/RubyXL/PageSetup.html +1 -1
  287. data/rdoc/RubyXL/PageSetupProperties.html +1 -1
  288. data/rdoc/RubyXL/Pane.html +1 -1
  289. data/rdoc/RubyXL/Parser.html +4 -4
  290. data/rdoc/RubyXL/PatternFill.html +1 -1
  291. data/rdoc/RubyXL/PhoneticProperties.html +1 -1
  292. data/rdoc/RubyXL/PhoneticRun.html +1 -1
  293. data/rdoc/RubyXL/PivotArea.html +1 -1
  294. data/rdoc/RubyXL/PivotCache.html +1 -1
  295. data/rdoc/RubyXL/PivotCacheDefinitionFile.html +1 -1
  296. data/rdoc/RubyXL/PivotCaches.html +1 -1
  297. data/rdoc/RubyXL/PivotReference.html +1 -1
  298. data/rdoc/RubyXL/PivotReferences.html +1 -1
  299. data/rdoc/RubyXL/PivotTableFile.html +1 -1
  300. data/rdoc/RubyXL/PivotTableSelection.html +1 -1
  301. data/rdoc/RubyXL/PresetGeometry.html +1 -1
  302. data/rdoc/RubyXL/PrintOptions.html +1 -1
  303. data/rdoc/RubyXL/PrinterSettingsFile.html +1 -20
  304. data/rdoc/RubyXL/ProtectedRange.html +1 -1
  305. data/rdoc/RubyXL/ProtectedRanges.html +1 -1
  306. data/rdoc/RubyXL/Protection.html +1 -1
  307. data/rdoc/RubyXL/RID.html +1 -1
  308. data/rdoc/RubyXL/RawOOXML.html +1 -1
  309. data/rdoc/RubyXL/Reference.html +60 -60
  310. data/rdoc/RubyXL/Relationship.html +1 -1
  311. data/rdoc/RubyXL/RelationshipSupport.html +1 -1
  312. data/rdoc/RubyXL/RelationshipSupport/ClassMehods.html +1 -1
  313. data/rdoc/RubyXL/RichText.html +1 -1
  314. data/rdoc/RubyXL/RichTextRun.html +1 -1
  315. data/rdoc/RubyXL/Row.html +1 -1
  316. data/rdoc/RubyXL/RunProperties.html +1 -1
  317. data/rdoc/RubyXL/Scenario.html +2 -2
  318. data/rdoc/RubyXL/Scenarios.html +1 -1
  319. data/rdoc/RubyXL/Selection.html +1 -1
  320. data/rdoc/RubyXL/ShapeGuide.html +1 -1
  321. data/rdoc/RubyXL/ShapeTextRectangle.html +1 -1
  322. data/rdoc/RubyXL/SharedStringsTable.html +25 -25
  323. data/rdoc/RubyXL/Sheet.html +1 -1
  324. data/rdoc/RubyXL/SheetCalculationProperties.html +1 -1
  325. data/rdoc/RubyXL/SheetData.html +1 -1
  326. data/rdoc/RubyXL/Sheets.html +1 -1
  327. data/rdoc/RubyXL/SlicerCacheFile.html +1 -1
  328. data/rdoc/RubyXL/SlicerFile.html +1 -1
  329. data/rdoc/RubyXL/SmartTagProperties.html +1 -1
  330. data/rdoc/RubyXL/SmartTagType.html +1 -1
  331. data/rdoc/RubyXL/SmartTagTypes.html +1 -1
  332. data/rdoc/RubyXL/SmartTags.html +1 -1
  333. data/rdoc/RubyXL/SortCondition.html +1 -1
  334. data/rdoc/RubyXL/SortState.html +1 -1
  335. data/rdoc/RubyXL/Sqref.html +5 -5
  336. data/rdoc/RubyXL/Stop.html +1 -1
  337. data/rdoc/RubyXL/StringNode.html +1 -1
  338. data/rdoc/RubyXL/StringNodeW3C.html +1 -1
  339. data/rdoc/RubyXL/StringValue.html +1 -1
  340. data/rdoc/RubyXL/Stylesheet.html +1 -1
  341. data/rdoc/RubyXL/TableFile.html +1 -1
  342. data/rdoc/RubyXL/TableParts.html +1 -1
  343. data/rdoc/RubyXL/TableStyle.html +1 -1
  344. data/rdoc/RubyXL/TableStyles.html +1 -1
  345. data/rdoc/RubyXL/Text.html +6 -6
  346. data/rdoc/RubyXL/Theme.html +1 -1
  347. data/rdoc/RubyXL/ThemeElements.html +1 -1
  348. data/rdoc/RubyXL/ThumbnailFile.html +1 -1
  349. data/rdoc/RubyXL/Top10.html +1 -1
  350. data/rdoc/RubyXL/VMLDrawingFile.html +1 -1
  351. data/rdoc/RubyXL/Variant.html +1 -1
  352. data/rdoc/RubyXL/Vector.html +1 -1
  353. data/rdoc/RubyXL/VectorValue.html +1 -1
  354. data/rdoc/RubyXL/VisualProperties.html +1 -1
  355. data/rdoc/RubyXL/WebPublishObject.html +1 -1
  356. data/rdoc/RubyXL/WebPublishObjects.html +1 -1
  357. data/rdoc/RubyXL/WebPublishingItem.html +1 -1
  358. data/rdoc/RubyXL/WebPublishingItems.html +1 -1
  359. data/rdoc/RubyXL/WebPublishingProperties.html +1 -1
  360. data/rdoc/RubyXL/Workbook.html +1 -1
  361. data/rdoc/RubyXL/WorkbookProperties.html +1 -1
  362. data/rdoc/RubyXL/WorkbookProtection.html +1 -1
  363. data/rdoc/RubyXL/WorkbookRoot.html +46 -46
  364. data/rdoc/RubyXL/WorkbookView.html +1 -1
  365. data/rdoc/RubyXL/WorkbookViews.html +1 -1
  366. data/rdoc/RubyXL/Worksheet.html +1 -1
  367. data/rdoc/RubyXL/WorksheetDimensions.html +1 -1
  368. data/rdoc/RubyXL/WorksheetFormatProperties.html +1 -1
  369. data/rdoc/RubyXL/WorksheetProperties.html +1 -1
  370. data/rdoc/RubyXL/WorksheetProtection.html +1 -1
  371. data/rdoc/RubyXL/WorksheetView.html +1 -1
  372. data/rdoc/RubyXL/WorksheetViews.html +1 -1
  373. data/rdoc/RubyXL/XF.html +1 -1
  374. data/rdoc/created.rid +37 -37
  375. data/rdoc/index.html +2 -8
  376. data/rdoc/js/search_index.js +1 -1
  377. data/rdoc/table_of_contents.html +77 -101
  378. data/rubyXL.gemspec +4 -4
  379. metadata +3 -3
@@ -17,20 +17,20 @@ module RubyXL
17
17
  end
18
18
  end
19
19
 
20
- # http://www.schemacentral.com/sc/ooxml/e-ssml_ext-1.html
21
- class Extension < RawOOXML
22
- define_attribute(:uri, :string)
23
- define_element_name 'ext'
24
- end
25
-
26
- # http://www.schemacentral.com/sc/ooxml/e-ssml_extLst-1.html
27
- class ExtensionStorageArea < OOXMLObject
28
- define_child_node(RubyXL::Extension, :collection => true)
29
- define_element_name 'extLst'
30
- end
31
-
32
- class AlternateContent < RawOOXML
33
- define_element_name 'mc:AlternateContent'
34
- end
35
-
36
- end
20
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_ext-1.html
21
+ class Extension < RawOOXML
22
+ define_attribute(:uri, :string)
23
+ define_element_name 'ext'
24
+ end
25
+
26
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_extLst-1.html
27
+ class ExtensionStorageArea < OOXMLObject
28
+ define_child_node(RubyXL::Extension, :collection => true)
29
+ define_element_name 'extLst'
30
+ end
31
+
32
+ class AlternateContent < RawOOXML
33
+ define_element_name 'mc:AlternateContent'
34
+ end
35
+
36
+ end
@@ -3,51 +3,51 @@ require 'rubyXL/objects/simple_types'
3
3
 
4
4
  module RubyXL
5
5
 
6
- # http://www.datypic.com/sc/ooxml/e-ssml_stop-1.html
7
- class Stop < OOXMLObject
8
- define_attribute(:position, :double, :required => true)
9
- define_child_node(RubyXL::Color)
10
- define_element_name 'stop'
11
- end
12
-
13
- # http://www.schemacentral.com/sc/ooxml/e-ssml_patternFill-1.html
14
- class PatternFill < OOXMLObject
15
- define_attribute(:patternType, RubyXL::ST_PatternType)
16
- define_child_node(RubyXL::Color, :node_name => :fgColor )
17
- define_child_node(RubyXL::Color, :node_name => :bgColor )
18
- define_element_name 'patternFill'
19
- end
20
-
21
- # http://www.schemacentral.com/sc/ooxml/e-ssml_gradientFill-1.html
22
- class GradientFill < OOXMLObject
23
- define_attribute(:type, RubyXL::ST_GradientType, :default => 'linear')
24
- define_attribute(:degree, :double, :default => 0)
25
- define_attribute(:left, :double, :default => 0)
26
- define_attribute(:right, :double, :default => 0)
27
- define_attribute(:top, :double, :default => 0)
28
- define_attribute(:bottom, :double, :default => 0)
29
- define_child_node(RubyXL::Stop, :collection => true)
30
- define_element_name 'gradientFill'
31
- end
32
-
33
- # http://www.schemacentral.com/sc/ooxml/e-ssml_fill-1.html
34
- class Fill < OOXMLObject
35
- define_child_node(RubyXL::PatternFill)
36
- define_child_node(RubyXL::GradientFill)
37
- define_element_name 'fill'
38
- end
39
-
40
- # http://www.schemacentral.com/sc/ooxml/e-ssml_fills-1.html
41
- class Fills < OOXMLContainerObject
42
- define_child_node(RubyXL::Fill, :collection => :with_count)
43
- define_element_name 'fills'
44
-
45
- def self.defaults
46
- self.new(:_ => [
47
- RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'none')),
48
- RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'gray125'))
49
- ])
50
- end
51
- end
52
-
53
- end
6
+ # http://www.datypic.com/sc/ooxml/e-ssml_stop-1.html
7
+ class Stop < OOXMLObject
8
+ define_attribute(:position, :double, :required => true)
9
+ define_child_node(RubyXL::Color)
10
+ define_element_name 'stop'
11
+ end
12
+
13
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_patternFill-1.html
14
+ class PatternFill < OOXMLObject
15
+ define_attribute(:patternType, RubyXL::ST_PatternType)
16
+ define_child_node(RubyXL::Color, :node_name => :fgColor )
17
+ define_child_node(RubyXL::Color, :node_name => :bgColor )
18
+ define_element_name 'patternFill'
19
+ end
20
+
21
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_gradientFill-1.html
22
+ class GradientFill < OOXMLObject
23
+ define_attribute(:type, RubyXL::ST_GradientType, :default => 'linear')
24
+ define_attribute(:degree, :double, :default => 0)
25
+ define_attribute(:left, :double, :default => 0)
26
+ define_attribute(:right, :double, :default => 0)
27
+ define_attribute(:top, :double, :default => 0)
28
+ define_attribute(:bottom, :double, :default => 0)
29
+ define_child_node(RubyXL::Stop, :collection => true)
30
+ define_element_name 'gradientFill'
31
+ end
32
+
33
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_fill-1.html
34
+ class Fill < OOXMLObject
35
+ define_child_node(RubyXL::PatternFill)
36
+ define_child_node(RubyXL::GradientFill)
37
+ define_element_name 'fill'
38
+ end
39
+
40
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_fills-1.html
41
+ class Fills < OOXMLContainerObject
42
+ define_child_node(RubyXL::Fill, :collection => :with_count)
43
+ define_element_name 'fills'
44
+
45
+ def self.defaults
46
+ self.new(:_ => [
47
+ RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'none')),
48
+ RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'gray125'))
49
+ ])
50
+ end
51
+ end
52
+
53
+ end
@@ -1,120 +1,120 @@
1
- require 'rubyXL/objects/ooxml_object'
2
- require 'rubyXL/objects/simple_types'
3
- require 'rubyXL/objects/extensions'
4
-
5
- module RubyXL
6
-
7
- # http://www.schemacentral.com/sc/ooxml/e-ssml_dateGroupItem-1.html
8
- class DateGroupItem < OOXMLObject
9
- define_attribute(:year, :int, :required => true)
10
- define_attribute(:month, :int)
11
- define_attribute(:day, :int)
12
- define_attribute(:hour, :int)
13
- define_attribute(:minute, :int)
14
- define_attribute(:second, :int)
15
- define_attribute(:dateTimeGrouping, RubyXL::ST_DateTimeGrouping)
16
- define_element_name 'dateGroupItem'
17
- end
18
-
19
- # http://www.schemacentral.com/sc/ooxml/e-ssml_filters-1.html
20
- class FilterContainer < OOXMLObject
21
- define_attribute(:blank, :bool, :default => false)
22
- define_attribute(:calendarType, RubyXL::ST_CalendarType, :default => 'none')
23
- define_child_node(RubyXL::StringValue, :collection => true, :accessor => :filters, :node_name => :filter)
24
- define_child_node(RubyXL::DateGroupItem, :collection => true, :accessor => :date_group_items)
25
- define_element_name 'filters'
26
- end
27
-
28
- # http://www.schemacentral.com/sc/ooxml/e-ssml_top10-1.html
29
- class Top10 < OOXMLObject
30
- define_attribute(:top, :bool, :default => true)
31
- define_attribute(:percent, :bool, :default => false)
32
- define_attribute(:val, :double, :required => true)
33
- define_attribute(:filterVal, :double)
34
- define_element_name 'top10'
35
- end
36
-
37
- # http://www.schemacentral.com/sc/ooxml/e-ssml_customFilter-1.html
38
- class CustomFilter < OOXMLObject
39
- define_attribute(:operator, RubyXL::ST_FilterOperator, :default => 'equal')
40
- define_attribute(:val, :string)
41
- define_element_name 'customFilter'
42
- end
43
-
44
- # http://www.schemacentral.com/sc/ooxml/e-ssml_customFilters-1.html
45
- class CustomFilters < OOXMLContainerObject
46
- define_attribute(:and, :bool, :default => false)
47
- define_child_node(RubyXL::CustomFilter, :collection => true)
48
- define_element_name 'customFilters'
49
- end
50
-
51
- # http://www.schemacentral.com/sc/ooxml/e-ssml_dynamicFilter-1.html
52
- class DynamicFilter < OOXMLObject
53
- define_attribute(:type, RubyXL::ST_DynamicFilterType, :required => true)
54
- define_attribute(:val, :double)
55
- define_attribute(:maxVal, :double)
56
- define_element_name 'dynamicFilter'
57
- end
58
-
59
- # http://www.schemacentral.com/sc/ooxml/e-ssml_colorFilter-1.html
60
- class ColorFilter < OOXMLObject
61
- define_attribute(:dxfId, :string)
62
- define_attribute(:cellColor, :bool)
63
- define_element_name 'colorFilter'
64
- end
65
-
66
- # http://www.schemacentral.com/sc/ooxml/e-ssml_iconFilter-1.html
67
- class IconFilter < OOXMLObject
68
- define_attribute(:iconSet, RubyXL::ST_IconSetType)
69
- define_attribute(:iconId, :int)
70
- define_element_name 'iconFilter'
71
- end
72
-
73
- # http://www.schemacentral.com/sc/ooxml/e-ssml_filterColumn-1.html
74
- class AutoFilterColumn < OOXMLObject
75
- define_attribute(:colId, :int, :required => true)
76
- define_attribute(:hiddenButton, :bool, :default => false)
77
- define_attribute(:showButton, :bool, :default => true)
78
- define_child_node(RubyXL::FilterContainer)
79
- define_child_node(RubyXL::Top10)
80
- define_child_node(RubyXL::CustomFilters)
81
- define_child_node(RubyXL::DynamicFilter)
82
- define_child_node(RubyXL::ColorFilter)
83
- define_child_node(RubyXL::IconFilter)
84
- define_child_node(RubyXL::ExtensionStorageArea)
85
- define_element_name 'filterColumn'
86
- end
87
-
88
- # http://www.schemacentral.com/sc/ooxml/e-ssml_sortCondition-1.html
89
- class SortCondition < OOXMLObject
90
- define_attribute(:descending, :bool, :default => false)
91
- define_attribute(:sortBy, RubyXL::ST_SortBy, :default => 'value')
92
- define_attribute(:ref, :ref, :required => true)
93
- define_attribute(:customList, :string)
94
- define_attribute(:dxfId, :int)
95
- define_attribute(:iconSet, RubyXL::ST_IconSetType, :required => true, :default => '3Arrows')
96
- define_attribute(:iconId, :int)
97
- define_element_name 'sortCondition'
98
- end
99
-
100
- # http://www.schemacentral.com/sc/ooxml/e-ssml_sortState-2.html
101
- class SortState < OOXMLObject
102
- define_attribute(:columnSort, :bool, :default => false)
103
- define_attribute(:caseSensitive, :bool, :default => false)
104
- define_attribute(:sortMethod, RubyXL::ST_SortMethod, :default => 'none')
105
- define_attribute(:ref, :ref, :required => true)
106
- define_child_node(RubyXL::SortCondition, :collection => true)
107
- define_child_node(RubyXL::ExtensionStorageArea)
108
- define_element_name 'sortState'
109
- end
110
-
111
- # http://www.schemacentral.com/sc/ooxml/e-ssml_autoFilter-2.html
112
- class AutoFilter < OOXMLObject
113
- define_attribute(:ref, :ref)
114
- define_child_node(RubyXL::AutoFilterColumn)
115
- define_child_node(RubyXL::SortState)
116
- define_child_node(RubyXL::ExtensionStorageArea)
117
- define_element_name 'autoFilter'
118
- end
119
-
1
+ require 'rubyXL/objects/ooxml_object'
2
+ require 'rubyXL/objects/simple_types'
3
+ require 'rubyXL/objects/extensions'
4
+
5
+ module RubyXL
6
+
7
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_dateGroupItem-1.html
8
+ class DateGroupItem < OOXMLObject
9
+ define_attribute(:year, :int, :required => true)
10
+ define_attribute(:month, :int)
11
+ define_attribute(:day, :int)
12
+ define_attribute(:hour, :int)
13
+ define_attribute(:minute, :int)
14
+ define_attribute(:second, :int)
15
+ define_attribute(:dateTimeGrouping, RubyXL::ST_DateTimeGrouping)
16
+ define_element_name 'dateGroupItem'
17
+ end
18
+
19
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_filters-1.html
20
+ class FilterContainer < OOXMLObject
21
+ define_attribute(:blank, :bool, :default => false)
22
+ define_attribute(:calendarType, RubyXL::ST_CalendarType, :default => 'none')
23
+ define_child_node(RubyXL::StringValue, :collection => true, :accessor => :filters, :node_name => :filter)
24
+ define_child_node(RubyXL::DateGroupItem, :collection => true, :accessor => :date_group_items)
25
+ define_element_name 'filters'
26
+ end
27
+
28
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_top10-1.html
29
+ class Top10 < OOXMLObject
30
+ define_attribute(:top, :bool, :default => true)
31
+ define_attribute(:percent, :bool, :default => false)
32
+ define_attribute(:val, :double, :required => true)
33
+ define_attribute(:filterVal, :double)
34
+ define_element_name 'top10'
35
+ end
36
+
37
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_customFilter-1.html
38
+ class CustomFilter < OOXMLObject
39
+ define_attribute(:operator, RubyXL::ST_FilterOperator, :default => 'equal')
40
+ define_attribute(:val, :string)
41
+ define_element_name 'customFilter'
42
+ end
43
+
44
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_customFilters-1.html
45
+ class CustomFilters < OOXMLContainerObject
46
+ define_attribute(:and, :bool, :default => false)
47
+ define_child_node(RubyXL::CustomFilter, :collection => true)
48
+ define_element_name 'customFilters'
49
+ end
50
+
51
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_dynamicFilter-1.html
52
+ class DynamicFilter < OOXMLObject
53
+ define_attribute(:type, RubyXL::ST_DynamicFilterType, :required => true)
54
+ define_attribute(:val, :double)
55
+ define_attribute(:maxVal, :double)
56
+ define_element_name 'dynamicFilter'
57
+ end
58
+
59
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_colorFilter-1.html
60
+ class ColorFilter < OOXMLObject
61
+ define_attribute(:dxfId, :string)
62
+ define_attribute(:cellColor, :bool)
63
+ define_element_name 'colorFilter'
64
+ end
65
+
66
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_iconFilter-1.html
67
+ class IconFilter < OOXMLObject
68
+ define_attribute(:iconSet, RubyXL::ST_IconSetType)
69
+ define_attribute(:iconId, :int)
70
+ define_element_name 'iconFilter'
71
+ end
72
+
73
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_filterColumn-1.html
74
+ class AutoFilterColumn < OOXMLObject
75
+ define_attribute(:colId, :int, :required => true)
76
+ define_attribute(:hiddenButton, :bool, :default => false)
77
+ define_attribute(:showButton, :bool, :default => true)
78
+ define_child_node(RubyXL::FilterContainer)
79
+ define_child_node(RubyXL::Top10)
80
+ define_child_node(RubyXL::CustomFilters)
81
+ define_child_node(RubyXL::DynamicFilter)
82
+ define_child_node(RubyXL::ColorFilter)
83
+ define_child_node(RubyXL::IconFilter)
84
+ define_child_node(RubyXL::ExtensionStorageArea)
85
+ define_element_name 'filterColumn'
86
+ end
87
+
88
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_sortCondition-1.html
89
+ class SortCondition < OOXMLObject
90
+ define_attribute(:descending, :bool, :default => false)
91
+ define_attribute(:sortBy, RubyXL::ST_SortBy, :default => 'value')
92
+ define_attribute(:ref, :ref, :required => true)
93
+ define_attribute(:customList, :string)
94
+ define_attribute(:dxfId, :int)
95
+ define_attribute(:iconSet, RubyXL::ST_IconSetType, :required => true, :default => '3Arrows')
96
+ define_attribute(:iconId, :int)
97
+ define_element_name 'sortCondition'
98
+ end
99
+
100
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_sortState-2.html
101
+ class SortState < OOXMLObject
102
+ define_attribute(:columnSort, :bool, :default => false)
103
+ define_attribute(:caseSensitive, :bool, :default => false)
104
+ define_attribute(:sortMethod, RubyXL::ST_SortMethod, :default => 'none')
105
+ define_attribute(:ref, :ref, :required => true)
106
+ define_child_node(RubyXL::SortCondition, :collection => true)
107
+ define_child_node(RubyXL::ExtensionStorageArea)
108
+ define_element_name 'sortState'
109
+ end
110
+
111
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_autoFilter-2.html
112
+ class AutoFilter < OOXMLObject
113
+ define_attribute(:ref, :ref)
114
+ define_child_node(RubyXL::AutoFilterColumn)
115
+ define_child_node(RubyXL::SortState)
116
+ define_child_node(RubyXL::ExtensionStorageArea)
117
+ define_element_name 'autoFilter'
118
+ end
119
+
120
120
  end
@@ -26,16 +26,6 @@ module RubyXL
26
26
  define_child_node(RubyXL::StringValue, :node_name => :scheme)
27
27
  define_element_name 'font'
28
28
 
29
- def ==(other)
30
- (!(self.i && self.i.val) == !(other.i && other.i.val)) &&
31
- (!(self.b && self.b.val) == !(other.b && other.b.val)) &&
32
- (!(self.u && self.u.val) == !(other.u && other.u.val)) &&
33
- (!(self.strike && self.strike.val) == !(other.strike && other.strike.val)) &&
34
- ((self.name && self.name.val) == (other.name && other.name.val)) &&
35
- ((self.sz && self.sz.val) == (other.sz && other.sz.val)) &&
36
- (self.color == other.color) # Need to write proper comparison for color
37
- end
38
-
39
29
  def is_italic
40
30
  i && i.val
41
31
  end
@@ -1,24 +1,24 @@
1
- require 'rubyXL/objects/ooxml_object'
2
- require 'rubyXL/objects/simple_types'
3
-
4
- module RubyXL
5
-
6
- # http://www.schemacentral.com/sc/ooxml/e-ssml_f-1.html
7
- class Formula < OOXMLObject
8
- define_attribute(:_, :string, :accessor => :expression)
9
- define_attribute(:t, RubyXL::ST_CellFormulaType, :default => 'normal')
10
- define_attribute(:aca, :bool, :default => false)
11
- define_attribute(:ref, :ref)
12
- define_attribute(:dt2D, :bool, :default => false)
13
- define_attribute(:dtr, :bool, :default => false)
14
- define_attribute(:del1, :bool, :default => false)
15
- define_attribute(:del2, :bool, :default => false)
16
- define_attribute(:r1, :ref)
17
- define_attribute(:r2, :ref)
18
- define_attribute(:ca, :bool, :default => false)
19
- define_attribute(:si, :int)
20
- define_attribute(:bx, :bool, :default => false)
21
- define_element_name 'f'
22
- end
23
-
24
- end
1
+ require 'rubyXL/objects/ooxml_object'
2
+ require 'rubyXL/objects/simple_types'
3
+
4
+ module RubyXL
5
+
6
+ # http://www.schemacentral.com/sc/ooxml/e-ssml_f-1.html
7
+ class Formula < OOXMLObject
8
+ define_attribute(:_, :string, :accessor => :expression)
9
+ define_attribute(:t, RubyXL::ST_CellFormulaType, :default => 'normal')
10
+ define_attribute(:aca, :bool, :default => false)
11
+ define_attribute(:ref, :ref)
12
+ define_attribute(:dt2D, :bool, :default => false)
13
+ define_attribute(:dtr, :bool, :default => false)
14
+ define_attribute(:del1, :bool, :default => false)
15
+ define_attribute(:del2, :bool, :default => false)
16
+ define_attribute(:r1, :ref)
17
+ define_attribute(:r2, :ref)
18
+ define_attribute(:ca, :bool, :default => false)
19
+ define_attribute(:si, :int)
20
+ define_attribute(:bx, :bool, :default => false)
21
+ define_element_name 'f'
22
+ end
23
+
24
+ end
@@ -1,456 +1,443 @@
1
- require 'pathname'
2
-
3
- module RubyXL
4
- module OOXMLObjectClassMethods
5
- # Get the value of a [sub]class variable if it exists, or create the respective variable
6
- # with the passed-in +default+ (or +{}+, if not specified)
7
- #
8
- # Throughout this class, we are setting class variables through explicit method calls
9
- # rather than by directly addressing the name of the variable because of context issues:
10
- # addressing variable by name creates it in the context of defining class, while calling
11
- # the setter/getter method addresses it in the context of descendant class,
12
- # which is what we need.
13
- def obtain_class_variable(var_name, default = {})
14
- if class_variable_defined?(var_name) then
15
- self.class_variable_get(var_name)
16
- else
17
- self.class_variable_set(var_name, default)
18
- end
19
- end
20
-
21
- # Defines an attribute of OOXML object.
22
- # === Parameters
23
- # * +attribute_name+ - Name of the element attribute as seen in the source XML. Can be either <tt>"String"</tt> or <tt>:Symbol</tt>
24
- # * Special attibute name <tt>'_'</tt> (underscore) denotes the value of the element rather than attribute.
25
- # * +attribute_type+ - Specifies the conversion type for the attribute when parsing. Available options are:
26
- # * +:int+ - <tt>Integer</tt>
27
- # * +:uint+ - Unsigned <tt>Integer</tt>
28
- # * +:double+ - <tt>Float</tt></u>
29
- # * +:string+ - <tt>String</tt> (no conversion)
30
- # * +:sqref+ - RubyXL::Sqref
31
- # * +:ref+ - RubyXL::Reference
32
- # * +:bool+ - <tt>Boolean</tt> ("1" and "true" convert to +true+, others to +false+)
33
- # * one of +simple_types+ - <tt>String</tt>, plus the list of acceptable values is saved for future validation (not used yet).
34
- # * +extra_parameters+ - Hash of optional parameters as follows:
35
- # * +:accessor+ - Name of the accessor for this attribute to be defined on the object. If not provided, defaults to classidied +attribute_name+.
36
- # * +:default+ - Value this attribute defaults to if not explicitly provided.
37
- # * +:required+ - Whether this attribute is required when writing XML. If the value of the attrinute is not explicitly provided, +:default+ is written instead.
38
- # * +:computed+ - Do not store this attribute on +parse+, but do call the object-provided read accessor on +write_xml+.
39
- # ==== Examples
40
- # define_attribute(:outline, :bool, :default => true)
41
- # A <tt>Boolean</tt> attribute 'outline' with default value +true+ will be accessible by calling +obj.outline+
42
- # define_attribute(:uniqueCount, :int)
43
- # An <tt>Integer</tt> attribute 'uniqueCount' accessible as +obj.unique_count+
44
- # define_attribute(:_, :string, :accessor => :expression)
45
- # The value of the element will be accessible as a <tt>String</tt> by calling +obj.expression+
46
- # define_attribute(:errorStyle, %w{ stop warning information }, :default => 'stop',)
47
- # 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>
48
- def define_attribute(attr_name, attr_type, extra_params = {})
49
- attrs = obtain_class_variable(:@@ooxml_attributes)
50
- attr_hash = extra_params.merge({ :attr_type => attr_type })
51
- attr_hash[:accessor] ||= accessorize(attr_name)
52
- attrs[attr_name.to_s] = attr_hash
53
- self.send(:attr_accessor, attr_hash[:accessor]) unless attr_hash[:computed]
54
- end
55
-
56
- # Defines a child node of OOXML object.
57
- # === Parameters
58
- # * +klass+ - Class (descendant of RubyXL::OOXMLObject) of the child nodes. Child node objects will be produced by calling +parse+ method of that class.
59
- # * +extra_parameters+ - Hash of optional parameters as follows:
60
- # * +:accessor+ - Name of the accessor for this attribute to be defined on the object. If not provided, defaults to classidied +attribute_name+.
61
- # * +:node_name+ - Node name for the child node, in case it does not match the one defined by the +klass+.
62
- # * +:collection+ - Whether the child node should be treated as a single node or a collection of nodes:
63
- # * +false+ (default) - child node is directly accessible through the respective accessor;
64
- # * +true+ - a collection of child nodes is accessed as +Array+ through the respective accessor;
65
- # * +:with_count+ - same as +true+, but in addition, the attribute +count+ is defined on the current object, that will be automatically set to the number of elements in the collection at the start of +write_xml+ call.
66
- # ==== Examples
67
- # define_child_node(RubyXL::Alignment)
68
- # Define a singular child node parsed by the RubyXL::BorderEdge.parse() and accessed by the default <tt>obj.alignment</tt> accessor
69
- # define_child_node(RubyXL::Hyperlink, :collection => true, :accessor => :hyperlinks)
70
- # Define an array of nodes accessed by <tt>obj.hyperlinks</tt> accessor, each of which will be parsed by the RubyXL::Hyperlink.parse()
71
- # define_child_node(RubyXL::BorderEdge, :node_name => :left)
72
- # define_child_node(RubyXL::BorderEdge, :node_name => :right)
73
- # Use class RubyXL::BorderEdge when parsing both the elements <tt><left ...></tt> and <tt><right ...></tt> elements.
74
- # define_child_node(RubyXL::Font, :collection => :with_count, :accessor => :fonts)
75
- # 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
76
- def define_child_node(klass, extra_params = {})
77
- child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
78
- child_node_name = (extra_params[:node_name] || klass.class_variable_get(:@@ooxml_tag_name)).to_s
79
- accessor = (extra_params[:accessor] || accessorize(child_node_name)).to_sym
80
-
81
- child_nodes[child_node_name] = {
82
- :class => klass,
83
- :is_array => extra_params[:collection],
84
- :accessor => accessor
85
- }
86
-
87
- define_count_attribute if extra_params[:collection] == :with_count
88
-
89
- self.send(:attr_accessor, accessor)
90
- end
91
-
92
- def define_count_attribute
93
- define_attribute(:count, :uint, :required => true)
94
- end
95
- private :define_count_attribute
96
-
97
- # Defines the name of the element that represents the current OOXML object. Should only be used once per object.
98
- # In case of different objects represented by the same class in different parts of OOXML tree, +:node_name+
99
- # extra parameter can be used to override the default element name.
100
- # === Parameters
101
- # * +element_name+
102
- # ==== Examples
103
- # define_element_name 'externalReference'
104
- def define_element_name(element_name)
105
- self.class_variable_set(:@@ooxml_tag_name, element_name)
106
- end
107
-
108
- def parse(node, known_namespaces = nil)
109
- node = Nokogiri::XML.parse(node) if node.is_a?(IO) || node.is_a?(String) || node.is_a?(Zip::InputStream)
110
-
111
- if node.is_a?(Nokogiri::XML::Document) then
112
- @namespaces = node.namespaces
113
- node = node.root
114
- # ignorable_attr = node.attributes['Ignorable']
115
- # @ignorables << ignorable_attr.value if ignorable_attr
116
- end
117
-
118
- obj = self.new
119
-
120
- known_attributes = obtain_class_variable(:@@ooxml_attributes)
121
-
122
- content_params = known_attributes['_']
123
- process_attribute(obj, node.text, content_params) if content_params
124
-
125
- node.attributes.each_pair { |attr_name, attr|
126
- attr_name = if attr.namespace then "#{attr.namespace.prefix}:#{attr.name}"
127
- else attr.name
128
- end
129
-
130
- attr_params = known_attributes[attr_name]
131
-
132
- next if attr_params.nil?
133
- # raise "Unknown attribute [#{attr_name}] for element [#{node.name}]" if attr_params.nil?
134
- process_attribute(obj, attr.value, attr_params) unless attr_params[:computed]
135
- }
136
-
137
- known_child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
138
-
139
- unless known_child_nodes.empty?
140
- known_namespaces ||= obtain_class_variable(:@@ooxml_namespaces)
141
-
142
- node.element_children.each { |child_node|
143
-
144
- ns = child_node.namespace
145
- prefix = known_namespaces[ns.href] || ns.prefix
146
-
147
- child_node_name = case prefix
148
- when '', nil then child_node.name
149
- else "#{prefix}:#{child_node.name}"
150
- end
151
-
152
- child_node_params = known_child_nodes[child_node_name]
153
- raise "Unknown child node [#{child_node_name}] for element [#{node.name}]" if child_node_params.nil?
154
- parsed_object = child_node_params[:class].parse(child_node, known_namespaces)
155
- if child_node_params[:is_array] then
156
- index = parsed_object.index_in_collection
157
-
158
- collection = if (self < RubyXL::OOXMLContainerObject) then obj
159
- else obj.send(child_node_params[:accessor])
160
- end
161
-
162
- if index.nil? then
163
- collection << parsed_object
164
- else
165
- collection[index] = parsed_object
166
- end
167
- else
168
- obj.send("#{child_node_params[:accessor]}=", parsed_object)
169
- end
170
- }
171
- end
172
-
173
- obj
174
- end
175
-
176
- private
177
- def accessorize(str)
178
- acc = str.to_s.dup
179
- acc.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
180
- acc.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
181
- acc.gsub!(':','_')
182
- acc.downcase.to_sym
183
- end
184
-
185
- def process_attribute(obj, raw_value, params)
186
- val = raw_value &&
187
- case params[:attr_type]
188
- when :double then Float(raw_value) # http://www.datypic.com/sc/xsd/t-xsd_double.html
189
- when :string then raw_value
190
- when Array then raw_value # Case of Simple Types
191
- when :sqref then RubyXL::Sqref.new(raw_value)
192
- when :ref then RubyXL::Reference.new(raw_value)
193
- when :bool then ['1', 'true'].include?(raw_value)
194
- when :int then Integer(raw_value)
195
- when :uint then
196
- v = Integer(raw_value)
197
- raise ArgumentError.new("invalid value for unsigned Integer(): \"#{raw_value}\"") if v < 0
198
- v
199
- end
200
- obj.send("#{params[:accessor]}=", val)
201
- end
202
-
203
- end
204
-
205
-
206
- module OOXMLObjectInstanceMethods
207
- def self.included(klass)
208
- klass.extend RubyXL::OOXMLObjectClassMethods
209
- end
210
-
211
- def obtain_class_variable(var_name, default = {})
212
- self.class.obtain_class_variable(var_name, default)
213
- end
214
- private :obtain_class_variable
215
-
216
- def initialize(params = {})
217
- obtain_class_variable(:@@ooxml_attributes).each_value { |v|
218
- instance_variable_set("@#{v[:accessor]}", params[v[:accessor]]) unless v[:computed]
219
- }
220
-
221
- init_child_nodes(params)
222
-
223
- instance_variable_set("@count", 0) if obtain_class_variable(:@@ooxml_countable, false)
224
- end
225
-
226
- def init_child_nodes(params)
227
- obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
228
-
229
- initial_value =
230
- if params.has_key?(v[:accessor]) then params[v[:accessor]]
231
- elsif v[:is_array] then []
232
- else nil
233
- end
234
-
235
- instance_variable_set("@#{v[:accessor]}", initial_value)
236
- }
237
- end
238
- private :init_child_nodes
239
-
240
- # Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual
241
- # generation, +before_write_xml()+ is called to perform last-minute cleanup and validation operations; if it
242
- # returns +false+, an empty string is returned (rather than +nil+, so Nokogiri::XML's <tt>&lt;&lt;</tt> operator
243
- # can be used without additional +nil+ checking)
244
- # === Parameters
245
- # * +xml+ - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.
246
- # * +node_name_override+ - if present, is used instead of the default element name for this object provided by +define_element_name+
247
- # ==== Examples
248
- # obj.write_xml()
249
- # Creates a new empty +Nokogiri::XML+, populates it with the OOXML structure as described in the respective definition, and returns the resulting +Nokogiri::XML+ object.
250
- # obj.write_xml(seed_xml)
251
- # Using the passed-in +Nokogiri+ +xml+ object, creates a new element corresponding to +obj+ according to its definition, along with all its properties and children, and returns the newly created element.
252
- # obj.write_xml(seed_xml, 'overriden_element_name')
253
- # Same as above, but uses the passed-in +node_name_override+ as the new element name, instead of its default name set by +define_element_name+.
254
- def write_xml(xml = nil, node_name_override = nil)
255
- if xml.nil? then
256
- seed_xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
257
- seed_xml.encoding = 'UTF-8'
258
- result = self.write_xml(seed_xml)
259
- return result if result == ''
260
- seed_xml << result
261
- return seed_xml.to_xml({ :indent => 0, :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML })
262
- end
263
-
264
- return '' unless before_write_xml
265
-
266
- # Populate namespaces, if any
267
- attrs = {}
268
- obtain_class_variable(:@@ooxml_namespaces).each_pair { |k, v| attrs[v.empty? ? 'xmlns' : "xmlns:#{v}"] = k }
269
-
270
- obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|
271
- val = self.send(v[:accessor])
272
-
273
- if val.nil? then
274
- next unless v[:required]
275
- val = v[:default]
276
- end
277
-
278
- val = val &&
279
- case v[:attr_type]
280
- when :bool then val ? '1' : '0'
281
- when :double then val.to_s.gsub(/\.0*\Z/, '') # Trim trailing zeroes
282
- else val
283
- end
284
-
285
- attrs[k] = val
286
- }
287
-
288
- element_text = attrs.delete('_')
289
- elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)
290
-
291
- child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
292
- child_nodes.each_pair { |child_node_name, child_node_params|
293
- node_obj = get_node_object(child_node_params)
294
- next if node_obj.nil?
295
-
296
- if node_obj.respond_to?(:write_xml) && !node_obj.equal?(self) then
297
- # If child node is either +OOXMLObject+, or +OOXMLContainerObject+ on its first (envelope) pass,
298
- # serialize that object.
299
- elem << node_obj.write_xml(xml, child_node_name)
300
- else
301
- # If child node is either vanilla +Array+, or +OOXMLContainerObject+ on its seconds (content) pass,
302
- # serialize write its members.
303
- node_obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
304
- end
305
- }
306
- elem
307
- end
308
-
309
- def dup
310
- new_copy = super
311
- new_copy.count = 0 if obtain_class_variable(:@@ooxml_countable, false)
312
- new_copy
313
- end
314
-
315
- # Prototype method. For sparse collections (+Rows+, +Cells+, etc.) must return index at which this object
316
- # is expected to reside in the collection. If +nil+ is returned, then object is simply added
317
- # to the end of the collection.
318
- def index_in_collection
319
- nil
320
- end
321
-
322
- def get_node_object(child_node_params)
323
- self.send(child_node_params[:accessor])
324
- end
325
- private :get_node_object
326
-
327
- # Subclass provided filter to perform last-minute operations (cleanup, count, etc.) immediately prior to write,
328
- # along with option to terminate the actual write if +false+ is returned (for example, to avoid writing
329
- # the collection's root node if the collection is empty).
330
- def before_write_xml
331
- #TODO# This will go away once containers are fully implemented.
332
- child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
333
- child_nodes.each_pair { |child_node_name, child_node_params|
334
- self.count = self.send(child_node_params[:accessor]).size if child_node_params[:is_array] == :with_count
335
- }
336
- true
337
- end
338
-
339
- end
340
-
341
- # Parent class for defining OOXML based objects (not unlike Rails' +ActiveRecord+!)
342
- # Most importantly, provides functionality of parsing such objects from XML,
343
- # and marshalling them to XML.
344
- class OOXMLObject
345
- include OOXMLObjectInstanceMethods
346
- end
347
-
348
- # Parent class for OOXML conainer objects (for example,
349
- # <tt>&lt;fonts&gt;&lt;font&gt;...&lt;/font&gt;&lt;font&gt;...&lt;/font&gt;&lt;/fonts&gt;</tt>
350
- # that obscures the top-level container, allowing direct access to the contents as +Array+.
351
- class OOXMLContainerObject < Array
352
- include OOXMLObjectInstanceMethods
353
-
354
- def initialize(params = {})
355
- array_content = params.delete(:_)
356
- super
357
- array_content.each_with_index { |v, i| self[i] = v } if array_content
358
- end
359
-
360
- def get_node_object(child_node_params)
361
- if child_node_params[:is_array] then self
362
- else super
363
- end
364
- end
365
- protected :get_node_object
366
-
367
- def init_child_nodes(params)
368
- obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
369
- next if v[:is_array] # Only one collection node allowed per OOXMLContainerObject, and it is contained in itself.
370
- instance_variable_set("@#{v[:accessor]}", params[v[:accessor]])
371
- }
372
- end
373
- protected :init_child_nodes
374
-
375
- def before_write_xml
376
- true
377
- end
378
-
379
- def inspect
380
- vars = [ super ]
381
- vars = self.instance_variables.each { |v| vars << "#{v}=#{instance_variable_get(v).inspect}" }
382
- "<#{self.class}: #{super} #{vars.join(", ")}>"
383
- end
384
-
385
- class << self
386
- def define_count_attribute
387
- # Count will be inherited from Array. so no need to define it explicitly.
388
- define_attribute(:count, :uint, :required => true, :computed => true)
389
- end
390
- protected :define_count_attribute
391
- end
392
-
393
- end
394
-
395
- # Extension class providing functionality for top-level OOXML objects that are represented by
396
- # their own <tt>.xml</tt> files in <tt>.xslx</tt> zip container.
397
- class OOXMLTopLevelObject < OOXMLObject
398
- SAVE_ORDER = 500
399
- ROOT = ::Pathname.new('/')
400
-
401
- attr_accessor :root
402
-
403
- # Prototype method. For top-level OOXML object, returns the path at which the current object's XML file
404
- # is located within the <tt>.xslx</tt> zip container.
405
- def xlsx_path
406
- raise 'Subclass responsebility'
407
- end
408
-
409
- # Sets the list of namespaces on this object to be added when writing out XML. Valid only on top-level objects.
410
- # === Parameters
411
- # * +namespace_hash+ - Hash of namespaces in the form of <tt>"prefix" => "url"</tt>
412
- # ==== Examples
413
- # set_namespaces('http://schemas.openxmlformats.org/spreadsheetml/2006/main' => '',
414
- # 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' => 'r')
415
- def self.set_namespaces(namespace_hash)
416
- self.class_variable_set(:@@ooxml_namespaces, namespace_hash)
417
- end
418
-
419
- # Generates the top-level OOXML object by parsing its XML file from the temporary
420
- # directory containing the unzipped contents of <tt>.xslx</tt>
421
- # === Parameters
422
- # * +dirpath+ - path to the directory with the unzipped <tt>.xslx</tt> contents.
423
- def self.parse_file(dirpath, file_path = nil)
424
- file_path = file_path || self.xlsx_path
425
-
426
- case dirpath
427
- when String then
428
- full_path = File.join(dirpath, file_path)
429
- return nil unless File.exist?(full_path)
430
- # Making sure that the file will be automatically closed immediately after it has been read
431
- File.open(full_path, 'r') { |f| parse(f) }
432
- when Zip::File then
433
- file_path = file_path.relative_path_from(::Pathname.new("/")) if file_path.absolute? # Zip doesn't like absolute paths.
434
- entry = dirpath.find_entry(file_path)
435
- # Accomodate for Nokogiri Java implementation which is incapable of reading from a stream
436
- entry && (entry.get_input_stream { |f| parse(defined?(JRUBY_VERSION) ? f.read : f) })
437
- end
438
- end
439
-
440
- # Saves the contents of the object as XML to respective location in <tt>.xslx</tt> zip container.
441
- # === Parameters
442
- # * +zipfile+ - ::Zip::File to which the resulting XNMML should be added.
443
- def add_to_zip(zip_stream)
444
- xml_string = write_xml
445
- return if xml_string.empty?
446
- zip_stream.put_next_entry(self.xlsx_path.relative_path_from(::Pathname.new("/")))
447
- zip_stream.write(xml_string)
448
- end
449
-
450
- def file_index
451
- root.rels_hash[self.class].index{ |f| f.equal?(self) }.to_i + 1
452
- end
453
-
454
- end
455
-
456
- end
1
+ require 'rubyXL/objects/reference'
2
+
3
+ module RubyXL
4
+ module OOXMLObjectClassMethods
5
+ # Get the value of a [sub]class variable if it exists, or create the respective variable
6
+ # with the passed-in +default+ (or +{}+, if not specified)
7
+ #
8
+ # Throughout this class, we are setting class variables through explicit method calls
9
+ # rather than by directly addressing the name of the variable because of context issues:
10
+ # addressing variable by name creates it in the context of defining class, while calling
11
+ # the setter/getter method addresses it in the context of descendant class,
12
+ # which is what we need.
13
+ def obtain_class_variable(var_name, default = {})
14
+ self.class_variable_get(var_name)
15
+ rescue NameError
16
+ self.class_variable_set(var_name, default)
17
+ end
18
+
19
+ # Defines an attribute of OOXML object.
20
+ # === Parameters
21
+ # * +attribute_name+ - Name of the element attribute as seen in the source XML. Can be either <tt>"String"</tt> or <tt>:Symbol</tt>
22
+ # * Special attibute name <tt>'_'</tt> (underscore) denotes the value of the element rather than attribute.
23
+ # * +attribute_type+ - Specifies the conversion type for the attribute when parsing. Available options are:
24
+ # * +:int+ - <tt>Integer</tt>
25
+ # * +:uint+ - Unsigned <tt>Integer</tt>
26
+ # * +:double+ - <tt>Float</tt></u>
27
+ # * +:string+ - <tt>String</tt> (no conversion)
28
+ # * +:sqref+ - RubyXL::Sqref
29
+ # * +:ref+ - RubyXL::Reference
30
+ # * +:bool+ - <tt>Boolean</tt> ("1" and "true" convert to +true+, others to +false+)
31
+ # * one of +simple_types+ - <tt>String</tt>, plus the list of acceptable values is saved for future validation (not used yet).
32
+ # * +extra_parameters+ - Hash of optional parameters as follows:
33
+ # * +:accessor+ - Name of the accessor for this attribute to be defined on the object. If not provided, defaults to classidied +attribute_name+.
34
+ # * +:default+ - Value this attribute defaults to if not explicitly provided.
35
+ # * +:required+ - Whether this attribute is required when writing XML. If the value of the attrinute is not explicitly provided, +:default+ is written instead.
36
+ # * +:computed+ - Do not store this attribute on +parse+, but do call the object-provided read accessor on +write_xml+.
37
+ # ==== Examples
38
+ # define_attribute(:outline, :bool, :default => true)
39
+ # A <tt>Boolean</tt> attribute 'outline' with default value +true+ will be accessible by calling +obj.outline+
40
+ # define_attribute(:uniqueCount, :int)
41
+ # An <tt>Integer</tt> attribute 'uniqueCount' accessible as +obj.unique_count+
42
+ # define_attribute(:_, :string, :accessor => :expression)
43
+ # The value of the element will be accessible as a <tt>String</tt> by calling +obj.expression+
44
+ # define_attribute(:errorStyle, %w{ stop warning information }, :default => 'stop',)
45
+ # 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>
46
+ def define_attribute(attr_name, attr_type, extra_params = {})
47
+ attrs = obtain_class_variable(:@@ooxml_attributes)
48
+ attr_hash = extra_params.merge({ :attr_type => attr_type })
49
+ attr_hash[:accessor] ||= accessorize(attr_name)
50
+ attrs[attr_name.to_s] = attr_hash
51
+ self.send(:attr_accessor, attr_hash[:accessor]) unless attr_hash[:computed]
52
+ end
53
+
54
+ # Defines a child node of OOXML object.
55
+ # === Parameters
56
+ # * +klass+ - Class (descendant of RubyXL::OOXMLObject) of the child nodes. Child node objects will be produced by calling +parse+ method of that class.
57
+ # * +extra_parameters+ - Hash of optional parameters as follows:
58
+ # * +:accessor+ - Name of the accessor for this attribute to be defined on the object. If not provided, defaults to classidied +attribute_name+.
59
+ # * +:node_name+ - Node name for the child node, in case it does not match the one defined by the +klass+.
60
+ # * +:collection+ - Whether the child node should be treated as a single node or a collection of nodes:
61
+ # * +false+ (default) - child node is directly accessible through the respective accessor;
62
+ # * +true+ - a collection of child nodes is accessed as +Array+ through the respective accessor;
63
+ # * +:with_count+ - same as +true+, but in addition, the attribute +count+ is defined on the current object, that will be automatically set to the number of elements in the collection at the start of +write_xml+ call.
64
+ # ==== Examples
65
+ # define_child_node(RubyXL::Alignment)
66
+ # Define a singular child node parsed by the RubyXL::BorderEdge.parse() and accessed by the default <tt>obj.alignment</tt> accessor
67
+ # define_child_node(RubyXL::Hyperlink, :collection => true, :accessor => :hyperlinks)
68
+ # Define an array of nodes accessed by <tt>obj.hyperlinks</tt> accessor, each of which will be parsed by the RubyXL::Hyperlink.parse()
69
+ # define_child_node(RubyXL::BorderEdge, :node_name => :left)
70
+ # define_child_node(RubyXL::BorderEdge, :node_name => :right)
71
+ # Use class RubyXL::BorderEdge when parsing both the elements <tt><left ...></tt> and <tt><right ...></tt> elements.
72
+ # define_child_node(RubyXL::Font, :collection => :with_count, :accessor => :fonts)
73
+ # 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
74
+ def define_child_node(klass, extra_params = {})
75
+ child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
76
+ child_node_name = (extra_params[:node_name] || klass.class_variable_get(:@@ooxml_tag_name)).to_s
77
+ accessor = (extra_params[:accessor] || accessorize(child_node_name)).to_sym
78
+
79
+ child_nodes[child_node_name] = {
80
+ :class => klass,
81
+ :is_array => extra_params[:collection],
82
+ :accessor => accessor
83
+ }
84
+
85
+ define_count_attribute if extra_params[:collection] == :with_count
86
+
87
+ self.send(:attr_accessor, accessor)
88
+ end
89
+
90
+ def define_count_attribute
91
+ define_attribute(:count, :uint, :required => true)
92
+ end
93
+ private :define_count_attribute
94
+
95
+ # Defines the name of the element that represents the current OOXML object. Should only be used once per object.
96
+ # In case of different objects represented by the same class in different parts of OOXML tree, +:node_name+
97
+ # extra parameter can be used to override the default element name.
98
+ # === Parameters
99
+ # * +element_name+
100
+ # ==== Examples
101
+ # define_element_name 'externalReference'
102
+ def define_element_name(element_name)
103
+ self.class_variable_set(:@@ooxml_tag_name, element_name)
104
+ end
105
+
106
+ def parse(node, known_namespaces = nil)
107
+ case node
108
+ when String, IO, Zip::InputStream then node = Nokogiri::XML.parse(node)
109
+ end
110
+
111
+ if node.is_a?(Nokogiri::XML::Document) then
112
+ @namespaces = node.namespaces
113
+ node = node.root
114
+ # ignorable_attr = node.attributes['Ignorable']
115
+ # @ignorables << ignorable_attr.value if ignorable_attr
116
+ end
117
+
118
+ obj = self.new
119
+
120
+ known_attributes = obtain_class_variable(:@@ooxml_attributes)
121
+
122
+ content_params = known_attributes['_']
123
+ process_attribute(obj, node.text, content_params) if content_params
124
+
125
+ node.attributes.each_pair { |attr_name, attr|
126
+ attr_name = if attr.namespace then "#{attr.namespace.prefix}:#{attr.name}"
127
+ else attr.name
128
+ end
129
+
130
+ attr_params = known_attributes[attr_name]
131
+
132
+ next if attr_params.nil?
133
+ # raise "Unknown attribute [#{attr_name}] for element [#{node.name}]" if attr_params.nil?
134
+ process_attribute(obj, attr.value, attr_params) unless attr_params[:computed]
135
+ }
136
+
137
+ known_child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
138
+
139
+ unless known_child_nodes.empty?
140
+ known_namespaces ||= obtain_class_variable(:@@ooxml_namespaces)
141
+
142
+ node.element_children.each { |child_node|
143
+
144
+ ns = child_node.namespace
145
+ prefix = known_namespaces[ns.href] || ns.prefix
146
+
147
+ child_node_name = case prefix
148
+ when '', nil then child_node.name
149
+ else "#{prefix}:#{child_node.name}"
150
+ end
151
+
152
+ child_node_params = known_child_nodes[child_node_name]
153
+ raise "Unknown child node [#{child_node_name}] for element [#{node.name}]" if child_node_params.nil?
154
+ parsed_object = child_node_params[:class].parse(child_node, known_namespaces)
155
+ if child_node_params[:is_array] then
156
+ index = parsed_object.index_in_collection
157
+
158
+ collection = if (self < RubyXL::OOXMLContainerObject) then obj
159
+ else obj.send(child_node_params[:accessor])
160
+ end
161
+
162
+ if index.nil? then
163
+ collection << parsed_object
164
+ else
165
+ collection[index] = parsed_object
166
+ end
167
+ else
168
+ obj.send("#{child_node_params[:accessor]}=", parsed_object)
169
+ end
170
+ }
171
+ end
172
+
173
+ obj
174
+ end
175
+
176
+ private
177
+ def accessorize(str)
178
+ acc = str.to_s.dup
179
+ acc.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
180
+ acc.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
181
+ acc.gsub!(':','_')
182
+ acc.downcase.to_sym
183
+ end
184
+
185
+ def process_attribute(obj, raw_value, params)
186
+ val = raw_value &&
187
+ case params[:attr_type]
188
+ when :double then Float(raw_value) # http://www.datypic.com/sc/xsd/t-xsd_double.html
189
+ when :string then raw_value
190
+ when Array then raw_value # Case of Simple Types
191
+ when :sqref then RubyXL::Sqref.new(raw_value)
192
+ when :ref then RubyXL::Reference.new(raw_value)
193
+ when :bool then ['1', 'true'].include?(raw_value)
194
+ when :int then Integer(raw_value)
195
+ when :uint then
196
+ v = Integer(raw_value)
197
+ raise ArgumentError.new("invalid value for unsigned Integer(): \"#{raw_value}\"") if v < 0
198
+ v
199
+ end
200
+ obj.send("#{params[:accessor]}=", val)
201
+ end
202
+
203
+ end
204
+
205
+
206
+ module OOXMLObjectInstanceMethods
207
+ def self.included(klass)
208
+ klass.extend RubyXL::OOXMLObjectClassMethods
209
+ end
210
+
211
+ def obtain_class_variable(var_name, default = {})
212
+ self.class.obtain_class_variable(var_name, default)
213
+ end
214
+ private :obtain_class_variable
215
+
216
+ def initialize(params = {})
217
+ obtain_class_variable(:@@ooxml_attributes).each_value { |v|
218
+ instance_variable_set("@#{v[:accessor]}", params[v[:accessor]]) unless v[:computed]
219
+ }
220
+
221
+ init_child_nodes(params)
222
+ end
223
+
224
+ def init_child_nodes(params)
225
+ obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
226
+
227
+ initial_value =
228
+ if params.has_key?(v[:accessor]) then params[v[:accessor]]
229
+ elsif v[:is_array] then []
230
+ else nil
231
+ end
232
+
233
+ instance_variable_set("@#{v[:accessor]}", initial_value)
234
+ }
235
+ end
236
+ private :init_child_nodes
237
+
238
+ def ==(other)
239
+ other.is_a?(self.class) &&
240
+ obtain_class_variable(:@@ooxml_attributes).all? { |k, v| self.send(v[:accessor]) == other.send(v[:accessor]) } &&
241
+ obtain_class_variable(:@@ooxml_child_nodes).all? { |k, v| self.send(v[:accessor]) == other.send(v[:accessor]) }
242
+ end
243
+
244
+ # Recursively write the OOXML object and all its children out as Nokogiri::XML. Immediately before the actual
245
+ # generation, +before_write_xml()+ is called to perform last-minute cleanup and validation operations; if it
246
+ # returns +false+, an empty string is returned (rather than +nil+, so Nokogiri::XML's <tt>&lt;&lt;</tt> operator
247
+ # can be used without additional +nil+ checking)
248
+ # === Parameters
249
+ # * +xml+ - Base Nokogiri::XML object used for building. If omitted, a blank document will be generated.
250
+ # * +node_name_override+ - if present, is used instead of the default element name for this object provided by +define_element_name+
251
+ # ==== Examples
252
+ # obj.write_xml()
253
+ # Creates a new empty +Nokogiri::XML+, populates it with the OOXML structure as described in the respective definition, and returns the resulting +Nokogiri::XML+ object.
254
+ # obj.write_xml(seed_xml)
255
+ # Using the passed-in +Nokogiri+ +xml+ object, creates a new element corresponding to +obj+ according to its definition, along with all its properties and children, and returns the newly created element.
256
+ # obj.write_xml(seed_xml, 'overriden_element_name')
257
+ # Same as above, but uses the passed-in +node_name_override+ as the new element name, instead of its default name set by +define_element_name+.
258
+ def write_xml(xml = nil, node_name_override = nil)
259
+ if xml.nil? then
260
+ seed_xml = Nokogiri::XML('<?xml version = "1.0" standalone ="yes"?>')
261
+ seed_xml.encoding = 'UTF-8'
262
+ result = self.write_xml(seed_xml)
263
+ return result if result == ''
264
+ seed_xml << result
265
+ return seed_xml.to_xml({ :indent => 0, :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML })
266
+ end
267
+
268
+ return '' unless before_write_xml
269
+
270
+ # Populate namespaces, if any
271
+ attrs = {}
272
+ obtain_class_variable(:@@ooxml_namespaces).each_pair { |k, v| attrs[v.empty? ? 'xmlns' : "xmlns:#{v}"] = k }
273
+
274
+ obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|
275
+ val = self.send(v[:accessor])
276
+
277
+ if val.nil? then
278
+ next unless v[:required]
279
+ val = v[:default]
280
+ end
281
+
282
+ val = val &&
283
+ case v[:attr_type]
284
+ when :bool then val ? '1' : '0'
285
+ when :double then val.to_s.gsub(/\.0*\Z/, '') # Trim trailing zeroes
286
+ else val
287
+ end
288
+
289
+ attrs[k] = val
290
+ }
291
+
292
+ element_text = attrs.delete('_')
293
+ elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)
294
+
295
+ child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
296
+ child_nodes.each_pair { |child_node_name, child_node_params|
297
+ node_obj = get_node_object(child_node_params)
298
+ next if node_obj.nil?
299
+
300
+ if node_obj.respond_to?(:write_xml) && !node_obj.equal?(self) then
301
+ # If child node is either +OOXMLObject+, or +OOXMLContainerObject+ on its first (envelope) pass,
302
+ # serialize that object.
303
+ elem << node_obj.write_xml(xml, child_node_name)
304
+ else
305
+ # If child node is either vanilla +Array+, or +OOXMLContainerObject+ on its seconds (content) pass,
306
+ # serialize write its members.
307
+ node_obj.each { |item| elem << item.write_xml(xml, child_node_name) unless item.nil? }
308
+ end
309
+ }
310
+ elem
311
+ end
312
+
313
+ # Prototype method. For sparse collections (+Rows+, +Cells+, etc.) must return index at which this object
314
+ # is expected to reside in the collection. If +nil+ is returned, then object is simply added
315
+ # to the end of the collection.
316
+ def index_in_collection
317
+ nil
318
+ end
319
+
320
+ def get_node_object(child_node_params)
321
+ self.send(child_node_params[:accessor])
322
+ end
323
+ private :get_node_object
324
+
325
+ # Subclass provided filter to perform last-minute operations (cleanup, count, etc.) immediately prior to write,
326
+ # along with option to terminate the actual write if +false+ is returned (for example, to avoid writing
327
+ # the collection's root node if the collection is empty).
328
+ def before_write_xml
329
+ #TODO# This will go away once containers are fully implemented.
330
+ child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
331
+ child_nodes.each_pair { |child_node_name, child_node_params|
332
+ self.count = self.send(child_node_params[:accessor]).size if child_node_params[:is_array] == :with_count
333
+ }
334
+ true
335
+ end
336
+
337
+ end
338
+
339
+ # Parent class for defining OOXML based objects (not unlike Rails' +ActiveRecord+!)
340
+ # Most importantly, provides functionality of parsing such objects from XML,
341
+ # and marshalling them to XML.
342
+ class OOXMLObject
343
+ include OOXMLObjectInstanceMethods
344
+ end
345
+
346
+ # Parent class for OOXML conainer objects (for example,
347
+ # <tt>&lt;fonts&gt;&lt;font&gt;...&lt;/font&gt;&lt;font&gt;...&lt;/font&gt;&lt;/fonts&gt;</tt>
348
+ # that obscures the top-level container, allowing direct access to the contents as +Array+.
349
+ class OOXMLContainerObject < Array
350
+ include OOXMLObjectInstanceMethods
351
+
352
+ def initialize(params = {})
353
+ array_content = params.delete(:_)
354
+ super
355
+ array_content.each_with_index { |v, i| self[i] = v } if array_content
356
+ end
357
+
358
+ def get_node_object(child_node_params)
359
+ if child_node_params[:is_array] then self
360
+ else super
361
+ end
362
+ end
363
+ protected :get_node_object
364
+
365
+ def init_child_nodes(params)
366
+ obtain_class_variable(:@@ooxml_child_nodes).each_value { |v|
367
+ next if v[:is_array] # Only one collection node allowed per OOXMLContainerObject, and it is contained in itself.
368
+ instance_variable_set("@#{v[:accessor]}", params[v[:accessor]])
369
+ }
370
+ end
371
+ protected :init_child_nodes
372
+
373
+ def before_write_xml
374
+ true
375
+ end
376
+
377
+ def inspect
378
+ vars = [ super ]
379
+ vars = self.instance_variables.each { |v| vars << "#{v}=#{instance_variable_get(v).inspect}" }
380
+ "<#{self.class}: #{super} #{vars.join(", ")}>"
381
+ end
382
+
383
+ class << self
384
+ def define_count_attribute
385
+ # Count will be inherited from Array. so no need to define it explicitly.
386
+ define_attribute(:count, :uint, :required => true, :computed => true)
387
+ end
388
+ protected :define_count_attribute
389
+ end
390
+
391
+ end
392
+
393
+ # Extension class providing functionality for top-level OOXML objects that are represented by
394
+ # their own <tt>.xml</tt> files in <tt>.xslx</tt> zip container.
395
+ class OOXMLTopLevelObject < OOXMLObject
396
+ SAVE_ORDER = 500
397
+ ROOT = ::Pathname.new('/')
398
+
399
+ attr_accessor :root
400
+
401
+ # Prototype method. For top-level OOXML object, returns the path at which the current object's XML file
402
+ # is located within the <tt>.xslx</tt> zip container.
403
+ def xlsx_path
404
+ raise 'Subclass responsebility'
405
+ end
406
+
407
+ # Sets the list of namespaces on this object to be added when writing out XML. Valid only on top-level objects.
408
+ # === Parameters
409
+ # * +namespace_hash+ - Hash of namespaces in the form of <tt>"prefix" => "url"</tt>
410
+ # ==== Examples
411
+ # set_namespaces('http://schemas.openxmlformats.org/spreadsheetml/2006/main' => '',
412
+ # 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' => 'r')
413
+ def self.set_namespaces(namespace_hash)
414
+ self.class_variable_set(:@@ooxml_namespaces, namespace_hash)
415
+ end
416
+
417
+ # Generates the top-level OOXML object by parsing its XML file from the temporary
418
+ # directory containing the unzipped contents of <tt>.xslx</tt>
419
+ # === Parameters
420
+ # * +dirpath+ - path to the directory with the unzipped <tt>.xslx</tt> contents.
421
+ def self.parse_file(zip_file, file_path)
422
+ entry = zip_file.find_entry(RubyXL::from_root(file_path))
423
+ # Accomodate for Nokogiri Java implementation which is incapable of reading from a stream
424
+ entry && (entry.get_input_stream { |f| parse(defined?(JRUBY_VERSION) ? f.read : f) })
425
+ end
426
+
427
+ # Saves the contents of the object as XML to respective location in <tt>.xslx</tt> zip container.
428
+ # === Parameters
429
+ # * +zipfile+ - ::Zip::File to which the resulting XNMML should be added.
430
+ def add_to_zip(zip_stream)
431
+ xml_string = write_xml
432
+ return if xml_string.empty?
433
+ zip_stream.put_next_entry(RubyXL::from_root(self.xlsx_path))
434
+ zip_stream.write(xml_string)
435
+ end
436
+
437
+ def file_index
438
+ root.rels_hash[self.class].index{ |f| f.equal?(self) }.to_i + 1
439
+ end
440
+
441
+ end
442
+
443
+ end