lib/rspreadsheet/worksheet.rb in rspreadsheet-0.2.0 vs lib/rspreadsheet/worksheet.rb in rspreadsheet-0.2.3
- old
+ new
@@ -3,154 +3,65 @@
# require 'forwardable'
module Rspreadsheet
class Worksheet
+ include XMLTiedArray
attr_accessor :name, :xmlnode
-# extend Forwardable
-# def_delegators :nonemptycells
+ def subitem_xml_options; {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'} end
def initialize(xmlnode_or_sheet_name)
- @rowcache=[]
+ @itemcache = Hash.new #TODO: move to module XMLTiedArray
# set up the @xmlnode according to parameter
case xmlnode_or_sheet_name
when LibXML::XML::Node
@xmlnode = xmlnode_or_sheet_name
when String
- @xmlnode = LibXML::XML::Node.new('table')
- ns = LibXML::XML::Namespace.new(@xmlnode, 'table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0')
- @xmlnode .namespaces.namespace = ns
- @xmlnode['table:name'] = xmlnode_or_sheet_name
+ @xmlnode = Tools.create_ns_node('table','table')
+ Tools.set_ns_attribute(@xmlnode,'table','name', xmlnode_or_sheet_name)
else raise 'Provide name or xml node to create a Worksheet object'
end
end
def rowxmlnode(rowi)
- find_subnode_respect_repeated(@xmlnode, rowi, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
+ find_my_subnode_respect_repeated(rowi, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
end
-
- def rowrange(rowi)
- find_subnode_range_respect_repeated(@xmlnode, rowi, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
+
+ def first_unused_row_index
+ find_first_unused_index_respect_repeated({:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
end
-
- def row_nonempty_cells_col_indexes(rowi)
- arowxmlnode = rowxmlnode(rowi)
- if arowxmlnode.nil?
- []
- else
- find_nonempty_subnode_indexes(arowxmlnode, {:xml_items_node_name => 'table-cell', :xml_repeated_attribute => 'number-columns-repeated'})
- end
- end
- def cellxmlnode(rowi,coli)
- arowxmlnode = rowxmlnode(rowi)
- if arowxmlnode.nil?
- nil
- else
- find_subnode_respect_repeated(arowxmlnode, coli, {:xml_items_node_name => 'table-cell', :xml_repeated_attribute => 'number-columns-repeated'})
- end
+ def insert_row_above(arowi)
+ insert_subitem_before(arowi)
end
-
- def cellrange(coli)
- find_subnode_range_respect_repeated(@xmlnode, rowi, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
- end
- def first_unused_row_index
- find_first_unused_index_respect_repeated(xmlnode, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
+ def insert_cell_before(arowi,acoli)
+ detach_row_in_xml(arowi)
+ rows(arowi).insert_subitem_before(acoli)
end
def detach_row_in_xml(rowi)
- return detach_subnode_respect_repeated(xmlnode, rowi, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
+ return detach_my_subnode_respect_repeated(rowi, {:xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated'})
end
- def detach_cell_in_xml(rowi,coli)
- rownode = detach_row_in_xml(rowi)
- return detach_subnode_respect_repeated(rownode, coli, {:xml_items_node_name => 'table-cell', :xml_repeated_attribute => 'number-columns-repeated'})
- end
- def detach_subnode_respect_repeated(axmlnode,aindex, options)
- index = 0
- axmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |node|
- repeated = (node.attributes[options[:xml_repeated_attribute]] || 1).to_i
- oldindex = index
- index = index+repeated
- if index>= aindex # found the node, now do the detachement
- ranges = [oldindex+1..aindex-1,aindex..aindex,aindex+1..index].reject {|range| range.size<1}
- ranges.each do |range|
- newnode = node.copy(true)
- Tools.set_ns_attribute(newnode,'table',options[:xml_repeated_attribute],range.size,1)
- node.prev = newnode
- end
- node.remove!
- return find_subnode_respect_repeated(axmlnode, aindex, options)
- end
- end
- # add outbound xmlnode
- [index+1..aindex-1,aindex..aindex].reject {|range| range.size<1}.each do |range|
- node = LibXML::XML::Node.new(options[:xml_items_node_name],nil, Tools.get_namespace('table'))
- Tools.set_ns_attribute(node,'table',options[:xml_repeated_attribute],range.size, 1)
- axmlnode << node
- end
- find_subnode_respect_repeated(axmlnode, aindex, options)
+ def nonemptycells
+ used_rows_range.collect{ |rowi| rows(rowi).nonemptycells }.flatten
end
-
- def find_subnode_respect_repeated(axmlnode, aindex, options)
- index = 0
- axmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |node|
- repeated = (node.attributes[options[:xml_repeated_attribute]] || 1).to_i
- index = index+repeated
- return node if index>= aindex
- end
- return nil
- end
- def find_subnode_range_respect_repeated(axmlnode, aindex, options)
- index = 0
- axmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |node|
- repeated = (node.attributes[options[:xml_repeated_attribute]] || 1).to_i
- if index+repeated >= aindex
- return (index+1..index+repeated)
- else
- index = index+repeated
- end
- end
- return (index+1..Float::INFINITY)
- end
- def find_nonempty_subnode_indexes(axmlnode, options)
- index = 0
- result = []
- axmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |node|
- repeated = (node.attributes[options[:xml_repeated_attribute]] || 1).to_i
- index = index + repeated
- if !(node.content.nil? or node.content.empty? or node.content =='') and (repeated==1)
- result << index
- end
- end
- return result
- end
- def find_first_unused_index_respect_repeated(axmlnode, options)
- index = 0
- axmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |node|
- repeated = (node.attributes[options[:xml_repeated_attribute]] || 1).to_i
- index = index+repeated
- end
- return index+1
- end
+ # rozšíření XMLTiedArray
+ def rows(rowi); subitem(rowi) end
+ def prepare_subitem(rowi); Row.new(self,rowi) end
+ def rowcache; @itemcache end
- def cells(r,c)
- rows(r).andand.cells(c)
- end
- def nonemptycells
- used_rows_range.collect{ |rowi| rows(rowi) }.collect { |row| row.nonemptycells }.flatten
- end
- def rows(rowi)
- @rowcache[rowi] ||= Row.new(self,rowi) unless rowi<=0
- end
## syntactic sugar follows
def [](r,c)
cells(r,c).andand.value
end
def []=(r,c,avalue)
cells(r,c).andand.value=avalue
+ end
+ def cells(r,c)
+ rows(r).andand.cells(c)
end
# allows syntax like sheet.F15
def method_missing method_name, *args, &block
if method_name.to_s.match(/^([A-Z]{1,3})(\d{1,8})(=?)$/)
row,col = Rspreadsheet::Tools.convert_cell_address_to_coordinates($~[1],$~[2])