rubyXL 3.2.0 → 3.2.1

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