rods 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +61 -49
- data/Rakefile +1 -1
- data/lib/rods.rb +101 -11
- data/rods.gemspec +2 -3
- metadata +5 -5
data/README
CHANGED
@@ -16,6 +16,8 @@
|
|
16
16
|
Licensed under the same terms as Ruby. No warranty is provided.
|
17
17
|
|
18
18
|
= Changelog
|
19
|
+
* 0.8.1
|
20
|
+
* Bug-Fix: methods insertRowBelow and insertCellAfter did not consider repetitions of previous element
|
19
21
|
* 0.8.0
|
20
22
|
* new function
|
21
23
|
* insertColumn
|
@@ -78,18 +80,25 @@
|
|
78
80
|
= What you must know
|
79
81
|
When you open a (new) spreadsheet in an application like OpenOffice.org, you'll see an infinity of empty cells and
|
80
82
|
might be tempted to assume that all these cells actually "exist" in the underlying file format/XML-structure.
|
81
|
-
This is not the case ! A "newly born" spreadsheet does not contain even a single cell ! They're created on demand
|
82
|
-
with
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
This is not the case ! A "newly born" spreadsheet does not contain even a single cell ! They're created on demand.
|
84
|
+
That is: If you write a cell with coordinates (10,10) into a new sheet only 2 rows and 2 cells are created
|
85
|
+
* an empty row with a repetition-attribute of 9 ( -> visible as row 1 to 9)
|
86
|
+
* a second row (visible on line 10)
|
87
|
+
* a single cell in the second row with a repetition-attribute of 9 ( -> visible as cells 1 to 9 in line 10)
|
88
|
+
* a single cell after the previous cell ( -> visible as cell 10 in line 10)
|
89
|
+
Things get complicated when you insert one or more rows, but we won't delve into implementation details here.
|
90
|
+
Suffice it to say, that
|
91
|
+
* if a single cell in a row has a visible value, the row as well as the cell 'exist' in the former sense, i.e.
|
92
|
+
they're definitely found by the routines get(Next|Previous)Existent(Row|Cell).
|
93
|
+
* the opposite does not apply: If a cell or row is visibly empty it COULD exist (and therefore be detectetd by
|
94
|
+
the former routines) or not. That is: When using the 'fast routines' you will from time to time stumble over
|
95
|
+
cells and rows not bearing any value, but nevertheless existing and are well advised to verify the return-values !
|
96
|
+
|
87
97
|
This is very important for using the interface appropriately: All routines matching 'Existent' merely return "living"
|
88
|
-
cells, while all other routines bearing a "get|Get" create a row or cell if necessary
|
89
|
-
within the new boundaries).
|
98
|
+
cells, while all other routines bearing a "get|Get" create a row or cell if necessary.
|
90
99
|
In other words: Use
|
91
100
|
* getNextExistentRow, getPreviousExistentRow, getNextExistentCell, getPreviousExistentCell
|
92
|
-
whenever you just want to read values you already have (seemlessly skipping visibly emtpy lines and columns) and
|
101
|
+
whenever you just want to read values you already have (seemlessly skipping most but not all visibly emtpy lines and columns) and
|
93
102
|
* getCell, writeGetCell and writeGetCellFromRow whenever you want a cell to be created if it does not exist (which
|
94
103
|
is undoubtedly the case, when you want to write to it or assign it a style) !
|
95
104
|
The first return nil, if an element does not exist yet, the second always return the desired element.
|
@@ -297,51 +306,51 @@
|
|
297
306
|
|
298
307
|
= Example 0.8.0
|
299
308
|
|
300
|
-
|
301
|
-
#
|
302
|
-
#
|
303
|
-
#
|
304
|
-
# #
|
305
|
-
# require 'rubygems'
|
306
|
-
# require 'rods'
|
309
|
+
#!/usr/bin/ruby
|
310
|
+
# coding: UTF-8
|
311
|
+
#
|
312
|
+
# Author: Dr. Heinz Breinlinger
|
307
313
|
#
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
#
|
319
|
-
|
320
|
-
|
321
|
-
|
314
|
+
require 'rubygems'
|
315
|
+
require 'rods'
|
316
|
+
|
317
|
+
mySheet=Rods.new("Template.ods")
|
318
|
+
1.upto(3){ |row|
|
319
|
+
1.upto(4){ |col|
|
320
|
+
mySheet.writeCell(row,col,"time","13:47")
|
321
|
+
}
|
322
|
+
}
|
323
|
+
#-----------------------------------------------------
|
324
|
+
# inserting new column -> shifting existing columns
|
325
|
+
#-----------------------------------------------------
|
326
|
+
mySheet.insertColumn(3)
|
327
|
+
1.upto(3){ |row|
|
328
|
+
mySheet.writeCell(row,3,"string","o' clock")
|
329
|
+
}
|
330
|
+
mySheet.saveAs("Test7.ods")
|
322
331
|
|
323
332
|
= Example 0.7.5
|
324
333
|
|
325
|
-
|
326
|
-
#
|
327
|
-
#
|
328
|
-
#
|
329
|
-
# #
|
330
|
-
# require 'rubygems'
|
331
|
-
# require 'rods'
|
334
|
+
#!/usr/bin/ruby
|
335
|
+
# coding: UTF-8
|
336
|
+
#
|
337
|
+
# Author: Dr. Heinz Breinlinger
|
332
338
|
#
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
339
|
+
require 'rubygems'
|
340
|
+
require 'rods'
|
341
|
+
|
342
|
+
mySheet=Rods.new("Template.ods")
|
343
|
+
mySheet.writeCell(1,1,"string","oneOne")
|
344
|
+
mySheet.writeCell(1,2,"string","oneTwo")
|
345
|
+
mySheet.writeCell(2,1,"string","twoOne") # finally becomes cell 3,1
|
346
|
+
mySheet.writeCell(2,2,"string","twoTwo") # finally becomes cell 3,2
|
347
|
+
row=mySheet.getRow(1)
|
348
|
+
newRow=mySheet.insertRowBelow(row)
|
349
|
+
mySheet.writeCell(2,1,"string","twoNewOne")
|
350
|
+
cell=mySheet.writeGetCell(2,2,"string","moved") # finally becomes cell "2,3"
|
351
|
+
mySheet.insertCellBefore(cell)
|
352
|
+
mySheet.writeCell(2,2,"string","twoNewTwoNew") # new cell "2,2"
|
353
|
+
mySheet.saveAs("Test6.ods")
|
345
354
|
|
346
355
|
= Example 0.7.0
|
347
356
|
|
@@ -483,6 +492,9 @@
|
|
483
492
|
# allow the XML-Parser to just continue from the "adjacent" node and
|
484
493
|
# return the previsous/next element without having to start from the top-node
|
485
494
|
# of the document over and over again !
|
495
|
+
# Caveat: According to the explanation above, you definitely know, that a cell/row
|
496
|
+
# exist, if they bear a value; if they don't, it depends on the sheets history,
|
497
|
+
# whether these are 'alive' and therefore accessible by the afore functions or not !
|
486
498
|
#---------------------------------------------------------------------------------
|
487
499
|
while(row=mySheet.getNextExistentRow(row))
|
488
500
|
i+=1
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('rods', '0.8.
|
5
|
+
Echoe.new('rods', '0.8.1') do |p|
|
6
6
|
p.description = "OpenOffice.org oocalc: Fast automated batch-processing of spreadsheets (*.ods) conforming to Open Document Format v1.1. used by e.g. OpenOffice.org and LibreOffice. Please see screenshot and Rdoc-Documentation at http://ruby.homelinux.com/ruby/rods/. You can contact me at rods.ruby@online.de (and tell me about your experiences or drop me a line, if you like it ;-)"
|
7
7
|
p.summary = "Automation of OpenOffice/LibreOffice by batch-processing of spreadsheets conforming to Open Document v1.1"
|
8
8
|
p.url = "http://ruby.homelinux.com/ruby/rods/"
|
data/lib/rods.rb
CHANGED
@@ -435,7 +435,6 @@ class Rods
|
|
435
435
|
#-------------------------------------------------------------------------
|
436
436
|
def renameTable(oldName,newName)
|
437
437
|
die("renameTable: table '#{oldName}' does not exist") unless (@tables.has_key?(oldName))
|
438
|
-
# die("renameTable: table '#{oldName}' cannot be renamed as it is the current table !") if (oldName == @currentTableName)
|
439
438
|
#------------------------------------------------------
|
440
439
|
# XML-Tree anpassen
|
441
440
|
#------------------------------------------------------
|
@@ -810,11 +809,11 @@ class Rods
|
|
810
809
|
else
|
811
810
|
text=textElement.text
|
812
811
|
if(! text)
|
813
|
-
|
812
|
+
text=""
|
814
813
|
end
|
815
814
|
type=cell.attributes["office:value-type"]
|
816
815
|
if(! type)
|
817
|
-
|
816
|
+
type="string"
|
818
817
|
end
|
819
818
|
text=normalizeText(text,type)
|
820
819
|
return text,type
|
@@ -2599,12 +2598,12 @@ class Rods
|
|
2599
2598
|
# Also consider that you have to search for the external (i.e. visible)
|
2600
2599
|
# represenation of a cell's content, not it's internal computational value.
|
2601
2600
|
# For instance, when looking for a currency value of 1525 (that is shown as
|
2602
|
-
# '1.525
|
2601
|
+
# '1.525 EUR'), you'll have to code
|
2603
2602
|
#
|
2604
|
-
#
|
2605
|
-
#
|
2606
|
-
#
|
2607
|
-
#
|
2603
|
+
# result=mySheet.getCellsAndIndicesFor('1[.,]525')
|
2604
|
+
# result.each{ |cellHash|
|
2605
|
+
# puts("Found #{cellHash[:cell] on #{cellHash[:row] - #{cellHash[:col]")
|
2606
|
+
# }
|
2608
2607
|
#-------------------------------------------------------------------------
|
2609
2608
|
def getCellsAndIndicesFor(content)
|
2610
2609
|
die("getCellsAndIndicesFor: 'content' is not of typ String") unless (content.class.to_s == "String")
|
@@ -2776,8 +2775,16 @@ class Rods
|
|
2776
2775
|
def insertCellAfter(cell)
|
2777
2776
|
newCell=createCell(1)
|
2778
2777
|
cell.next_sibling=newCell
|
2778
|
+
#-----------------------------------------------------------------------
|
2779
|
+
# Cave: etwaige Wiederholungen uebertragen
|
2780
|
+
#-----------------------------------------------------------------------
|
2781
|
+
repetitions=cell.attributes["table:number-columns-repeated"]
|
2782
|
+
if(repetitions)
|
2783
|
+
cell.attributes.delete("table:number-columns-repeated")
|
2784
|
+
newCell.next_sibling=createCell(repetitions.to_i)
|
2785
|
+
end
|
2779
2786
|
#-----------------------------------------
|
2780
|
-
# bisherige Tabellenbreite
|
2787
|
+
# bisherige Tabellenbreite ueberschritten ?
|
2781
2788
|
#-----------------------------------------
|
2782
2789
|
lengthOfRow=getNumberOfSiblings(cell)
|
2783
2790
|
if(lengthOfRow > @tables[@currentTableName][WIDTH])
|
@@ -2805,6 +2812,14 @@ class Rods
|
|
2805
2812
|
def insertRowBelow(row)
|
2806
2813
|
newRow=createRow(1)
|
2807
2814
|
row.next_sibling=newRow
|
2815
|
+
#-----------------------------------------------------------------------
|
2816
|
+
# Cave: etwaige Wiederholungen uebertragen
|
2817
|
+
#-----------------------------------------------------------------------
|
2818
|
+
repetitions=row.attributes["table:number-rows-repeated"]
|
2819
|
+
if(repetitions)
|
2820
|
+
row.attributes.delete("table:number-rows-repeated")
|
2821
|
+
newRow.next_sibling=createRow(repetitions.to_i)
|
2822
|
+
end
|
2808
2823
|
return newRow
|
2809
2824
|
end
|
2810
2825
|
##########################################################################
|
@@ -2838,6 +2853,81 @@ class Rods
|
|
2838
2853
|
end
|
2839
2854
|
end
|
2840
2855
|
##########################################################################
|
2856
|
+
# internal: returns cell at index if existent, nil otherwise
|
2857
|
+
# row=getRowIfExists(4)
|
2858
|
+
# if(row)
|
2859
|
+
# cell=getCellIfExists(row,7)
|
2860
|
+
# unless(cell) .....
|
2861
|
+
# end
|
2862
|
+
#-------------------------------------------------------------------------
|
2863
|
+
def getCellIfExists(row,index)
|
2864
|
+
return getElementIfExists(row,CELL,index)
|
2865
|
+
end
|
2866
|
+
##########################################################################
|
2867
|
+
# internal: returns row at index if existent, nil otherwise
|
2868
|
+
# if(mySheet.getRowIfExists(4))
|
2869
|
+
# ........
|
2870
|
+
# end
|
2871
|
+
#-------------------------------------------------------------------------
|
2872
|
+
def getRowIfExists(index)
|
2873
|
+
currentTable=@tables[@currentTableName][NODE]
|
2874
|
+
return getElementIfExists(currentTable,ROW,index)
|
2875
|
+
end
|
2876
|
+
##########################################################################
|
2877
|
+
# internal: examines, whether element of given type (row, cell, column) and index
|
2878
|
+
# exists or not.
|
2879
|
+
# Returns the element or nil if not existent.
|
2880
|
+
#-------------------------------------------------------------------------
|
2881
|
+
def getElementIfExists(parent,type,index)
|
2882
|
+
die("getElementIfExists: invalid type #{type}")
|
2883
|
+
die("getElementIfExists: parent is not a REXML::Element") unless (parent.class.to_s == "REXML::Element")
|
2884
|
+
die("getElementIfExists: index #{index} is not a Fixnum/Integer") unless (index.class.to_s == "Fixnum")
|
2885
|
+
die("getElementIfExists: invalid range for index #{index}") unless (index > 0)
|
2886
|
+
#--------------------------------------------------------------
|
2887
|
+
# Typabhaengige Vorbelegungen
|
2888
|
+
#--------------------------------------------------------------
|
2889
|
+
case type
|
2890
|
+
when CELL
|
2891
|
+
kindOfSelf="table:table-cell"
|
2892
|
+
kindOfParent="table:table-row"
|
2893
|
+
kindOfRepetition="table:number-columns-repeated"
|
2894
|
+
when COLUMN
|
2895
|
+
kindOfSelf="table:table-column"
|
2896
|
+
kindOfParent="table:table"
|
2897
|
+
kindOfRepetition="table:number-columns-repeated"
|
2898
|
+
when ROW
|
2899
|
+
kindOfSelf="table:table-row"
|
2900
|
+
kindOfParent="table:table"
|
2901
|
+
kindOfRepetition="table:number-rows-repeated"
|
2902
|
+
else
|
2903
|
+
die("getElementIfExists: invalid type #{type}")
|
2904
|
+
end
|
2905
|
+
#--------------------------------------------------------------
|
2906
|
+
# Ist Kind-Element mit Index in Vater-Element vorhanden ?
|
2907
|
+
#--------------------------------------------------------------
|
2908
|
+
i=0
|
2909
|
+
parent.elements.each(kindOfSelf){ |child|
|
2910
|
+
i+=1
|
2911
|
+
#----------------------------------------------------------
|
2912
|
+
# Index ueberschritten ? -> Ruecksprung mit nil
|
2913
|
+
# Index gefunden ? -> Rueckgabe des Elementes
|
2914
|
+
# sonst: etwaige Wiederholungen zaehlen
|
2915
|
+
#----------------------------------------------------------
|
2916
|
+
if (i > index)
|
2917
|
+
return nil
|
2918
|
+
elsif(i == index)
|
2919
|
+
tell("getElementIfExists: Found element #{type} at index #{index}")
|
2920
|
+
return child
|
2921
|
+
elsif(repetition=child.attributes[kindOfRepetition])
|
2922
|
+
index+=repetition.to_i-1 # '-1', da aktuelles Element ebenfalls als Wiederholung zaehlt
|
2923
|
+
end
|
2924
|
+
}
|
2925
|
+
#-------------------------------------------------------
|
2926
|
+
# Index liegt ausserhalb vorhandener Kind-Elemente
|
2927
|
+
#-------------------------------------------------------
|
2928
|
+
return nil
|
2929
|
+
end
|
2930
|
+
##########################################################################
|
2841
2931
|
# internal: Opens zip-file
|
2842
2932
|
#-------------------------------------------------------------------------
|
2843
2933
|
def open(file)
|
@@ -2857,7 +2947,7 @@ class Rods
|
|
2857
2947
|
:getCellFromRow, :getCell, :getRow, :renameTable, :setCurrentTable,
|
2858
2948
|
:insertTable, :deleteTable, :readCellFromRow, :readCell, :setAttributes, :writeStyleAbbr,
|
2859
2949
|
:setStyle, :printOfficeStyles, :printAutoStyles, :getNextExistentRow, :getPreviousExistentRow,
|
2860
|
-
|
2950
|
+
:getNextExistentCell, :getPreviousExistentCell, :insertTableAfter, :insertTableBefore,
|
2861
2951
|
:writeComment, :save, :saveAs, :initialize, :writeText, :getCellsAndIndicesFor,
|
2862
2952
|
:insertRowBelow, :insertRowAbove, :insertCellBefore, :insertCellAfter, :insertColumn
|
2863
2953
|
|
@@ -2868,5 +2958,5 @@ class Rods
|
|
2868
2958
|
:getAppropriateStyle, :checkStyleAttributes, :insertStyleAttributes, :cloneNode,
|
2869
2959
|
:writeStyle, :writeStyleXml, :style2Hash, :writeDefaultStyles, :writeXml,
|
2870
2960
|
:internalizeFormula, :getColorPalette, :open, :printStyles, :insertTableBeforeAfter,
|
2871
|
-
:insertColumnBefore
|
2961
|
+
:insertColumnBefore, :getElementIfExists, :getRowIfExists, :getCellIfExists
|
2872
2962
|
end # Klassenende
|
data/rods.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{rods}
|
5
|
-
s.version = "0.8.
|
5
|
+
s.version = "0.8.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Dr. Heinz Breinlinger"]
|
@@ -15,11 +15,10 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rods", "--main", "README"]
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = %q{rods}
|
18
|
-
s.rubygems_version = %q{1.
|
18
|
+
s.rubygems_version = %q{1.4.2}
|
19
19
|
s.summary = %q{Automation of OpenOffice/LibreOffice by batch-processing of spreadsheets conforming to Open Document v1.1}
|
20
20
|
|
21
21
|
if s.respond_to? :specification_version then
|
22
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
22
|
s.specification_version = 3
|
24
23
|
|
25
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rods
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 61
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 1
|
10
|
+
version: 0.8.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dr. Heinz Breinlinger
|
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
requirements: []
|
71
71
|
|
72
72
|
rubyforge_project: rods
|
73
|
-
rubygems_version: 1.
|
73
|
+
rubygems_version: 1.4.2
|
74
74
|
signing_key:
|
75
75
|
specification_version: 3
|
76
76
|
summary: Automation of OpenOffice/LibreOffice by batch-processing of spreadsheets conforming to Open Document v1.1
|