rods 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/Manifest +1 -0
  2. data/README +135 -0
  3. data/Rakefile +1 -1
  4. data/lib/rods.rb +368 -49
  5. data/rods.gemspec +4 -3
  6. metadata +7 -7
data/Manifest CHANGED
@@ -2,3 +2,4 @@ Manifest
2
2
  README
3
3
  Rakefile
4
4
  lib/rods.rb
5
+ rods.gemspec
data/README CHANGED
@@ -16,6 +16,11 @@
16
16
  Licensed under the same terms as Ruby. No warranty is provided.
17
17
 
18
18
  = Changelog
19
+ * 0.9.0
20
+ * added new methods
21
+ * insertRow, insertCell, insertCellFromRow, deleteCellBefore, deleteCellAfter, deleteCell, deleteCellFromRow,
22
+ deleteRowAbove, deleteRowBelow, deleteRow, deleteColumn, deleteRow2, deleteCell2
23
+ cf. Examples 0.9.0 a-e and read chapter "Caveat" below for performance-considerations !
19
24
  * 0.8.1
20
25
  * Bug-Fix: methods insertRowBelow and insertCellAfter did not consider repetitions of previous element
21
26
  * 0.8.0
@@ -304,6 +309,134 @@
304
309
  end
305
310
  end
306
311
 
312
+ = Example 0.9.0 a
313
+
314
+ #!/usr/bin/ruby
315
+ # coding: UTF-8
316
+ #
317
+ # Author: Dr. Heinz Breinlinger
318
+ #
319
+ require 'rubygems'
320
+ require 'rods'
321
+
322
+ mySheet=Rods.new("Template.ods")
323
+ 1.upto(3){ |row|
324
+ 1.upto(4){ |col|
325
+ mySheet.writeCell(row,col,"time","13:47")
326
+ }
327
+ }
328
+ mySheet.insertColumn(3)
329
+ 1.upto(3){ |row|
330
+ mySheet.writeCell(row,3,"string","o' clock")
331
+ }
332
+ mySheet.insertRow(2)
333
+ cell=mySheet.insertCell(3,3)
334
+ mySheet.writeText(cell,"string","insertCell")
335
+ row=mySheet.getRow(4)
336
+ row=mySheet.insertRowAbove(row)
337
+ mySheet.writeCell(4,1,"string","Willi")
338
+ cell=mySheet.insertCellFromRow(row,1)
339
+ mySheet.writeText(cell,"string","Supi")
340
+ mySheet.saveAs("Test8.ods")
341
+
342
+ = Example 0.9.0 b
343
+
344
+ #!/usr/bin/ruby
345
+ # coding: UTF-8
346
+ #
347
+ # Author: Dr. Heinz Breinlinger
348
+ #
349
+ require 'rubygems'
350
+ require 'rods'
351
+
352
+ mySheet=Rods.new("Template.ods")
353
+ mySheet.writeCell(1,1,"string","oneone")
354
+ cell=mySheet.writeGetCell(1,2,"string","onetwo")
355
+ mySheet.deleteCellBefore(cell)
356
+ cell=mySheet.writeGetCell(1,5,"string","onefive")
357
+ mySheet.deleteCellBefore(cell)
358
+
359
+ cellOne=mySheet.writeGetCell(5,1,"string","fiveone")
360
+ cellFive=mySheet.writeGetCell(5,5,"string","fivefive")
361
+ cellSix=mySheet.writeGetCell(5,6,"string","fivesix")
362
+ cellNine=mySheet.writeGetCell(5,9,"string","fivenine")
363
+ mySheet.deleteCellAfter(cellOne)
364
+ mySheet.deleteCellAfter(cellFive)
365
+ cell=mySheet.getCell(5,4)
366
+ mySheet.deleteCellBefore(cell)
367
+ cell=mySheet.getCell(5,4)
368
+ mySheet.deleteCellAfter(cell)
369
+ mySheet.deleteCell(5,2)
370
+ mySheet.deleteCell(5,3)
371
+ row=mySheet.getRow(5)
372
+ mySheet.deleteRowAbove(row)
373
+ mySheet.insertRow(2)
374
+ mySheet.insertRow(2)
375
+ row=mySheet.getRow(2)
376
+ mySheet.deleteRowBelow(row)
377
+ row=mySheet.getRow(1)
378
+ mySheet.deleteRowBelow(row)
379
+ row=mySheet.getRow(2)
380
+ mySheet.deleteRowBelow(row)
381
+ mySheet.deleteRow(2)
382
+ mySheet.deleteRow(1)
383
+ mySheet.deleteRow(1)
384
+ mySheet.saveAs("Test9.ods")
385
+
386
+ = Example 0.9.0 c
387
+
388
+ #!/usr/bin/ruby
389
+ # coding: UTF-8
390
+ #
391
+ # Author: Dr. Heinz Breinlinger
392
+ #
393
+ require 'rubygems'
394
+ require 'rods'
395
+
396
+ mySheet=Rods.new("Konten.ods")
397
+ startRow=mySheet.getRow(11)
398
+ i=0
399
+ while(row=mySheet.getNextExistentRow(startRow))
400
+ i+=1
401
+ puts("#{i}")
402
+ mySheet.deleteRow2(row)
403
+ end
404
+ mySheet.saveAs("Test10.ods")
405
+
406
+ = Example 0.9.0 d
407
+
408
+ #!/usr/bin/ruby
409
+ # coding: UTF-8
410
+ #
411
+ # Author: Dr. Heinz Breinlinger
412
+ #
413
+ require 'rubygems'
414
+ require 'rods'
415
+
416
+ mySheet=Rods.new("Konten.ods")
417
+ mySheet.deleteColumn(8)
418
+ mySheet.saveAs("Test11.ods")
419
+
420
+ = Example 0.9.0 e
421
+
422
+ #!/usr/bin/ruby
423
+ # coding: UTF-8
424
+ #
425
+ # Author: Dr. Heinz Breinlinger
426
+ #
427
+ require 'rubygems'
428
+ require 'rods'
429
+
430
+ mySheet=Rods.new("Konten.ods")
431
+ startCell=mySheet.getCell(12,1)
432
+ i=0
433
+ while(cell=mySheet.getNextExistentCell(startCell))
434
+ i+=1
435
+ puts("#{i}")
436
+ mySheet.deleteCell2(cell)
437
+ end
438
+ mySheet.saveAs("Test12.ods")
439
+
307
440
  = Example 0.8.0
308
441
 
309
442
  #!/usr/bin/ruby
@@ -516,6 +649,8 @@
516
649
  On the ATOM-Nettop I developed the gem, even the first script above took just 2-3 seconds and on my Core-i7-Notebook it was finished so quickly
517
650
  that I supposed it had halted on an immediate error, so: don't be concerned and just experiment :-).
518
651
 
652
+ The same considerations apply for the family of 'delete'-functions added in version 0.9.0 ! See the examples above.
653
+
519
654
  = Standards
520
655
  * Open Document Format for Office Applications (Open Document) v1.1 based on OpenOffice.org (OOo)
521
656
  * http://www.oasis-open.org/specs/#opendocumentv1.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.1') do |p|
5
+ Echoe.new('rods', '0.9.0') 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/"
@@ -37,6 +37,7 @@ class Rods
37
37
  AFTER="after"
38
38
  INDEX="index"
39
39
  NUMBER="number"
40
+ BOTH="both"
40
41
  WIDTHEXCEEDED="exceeded"
41
42
  ##########################################################################
42
43
  # Convenience-function to switch the default-style for the display of
@@ -259,6 +260,8 @@ class Rods
259
260
  # The child is created if it does not exist.
260
261
  #------------------------------------------------------------------------
261
262
  def getChildByIndex(parent,type,index)
263
+ die("getChildByIndex: 'parent' #{parent} is not a node") unless (parent.class.to_s == "REXML::Element")
264
+ die("getChildByIndex: 'index' #{index} is not a Fixnum") unless (index.class.to_s == "Fixnum")
262
265
  i=0
263
266
  lastElement=nil
264
267
  #----------------------------------------------------------------------
@@ -2151,8 +2154,8 @@ class Rods
2151
2154
  ##########################################################################
2152
2155
  # internal: Helper-Tool: Prints out all styles of given node in an indented ASCII-notation
2153
2156
  #------------------------------------------------------------------------
2154
- def printStyles(start,indent)
2155
- start.elements.each("*"){ |element|
2157
+ def printStyles(startNode,indent)
2158
+ startNode.elements.each("*"){ |element|
2156
2159
  #------------------------------------------
2157
2160
  # Tag extrahieren (Standard-Tag-Zeichen nach '<')
2158
2161
  #------------------------------------------
@@ -2541,9 +2544,19 @@ class Rods
2541
2544
  # to start from top-node of document to find row !
2542
2545
  # Returns previous row as a REXML::Element or nil if no element exists.
2543
2546
  # Cf. explanation in README !
2547
+ #
2544
2548
  #------------------------------------------------------------------------
2545
2549
  def getPreviousExistentRow(row)
2546
- return row.previous_sibling
2550
+ #----------------------------------------------------------------------
2551
+ # Cave: table:table-row und table:table-column sind Siblings !!!!
2552
+ # Letztere duerfen jedoch NICHT zurueckgegeben werden
2553
+ #----------------------------------------------------------------------
2554
+ previousSibling=row.previous_sibling
2555
+ if(previousSibling && previousSibling.elements["self::table:table-row"])
2556
+ return previousSibling
2557
+ else
2558
+ return nil
2559
+ end
2547
2560
  end
2548
2561
  ##########################################################################
2549
2562
  # Fast Routine to get the next cell, because XML-Parser does not have
@@ -2631,7 +2644,7 @@ class Rods
2631
2644
  unless (cell)
2632
2645
  die("getCellsAndIndicesFor: internal error: Could not extract parent-cell of textNode with #{content}")
2633
2646
  end
2634
- colIndex=getIndexOfElement(cell)
2647
+ colIndex=getIndex(cell)
2635
2648
  #-----------------------------------------------------
2636
2649
  # Zeile und Zeilenindex ermitteln
2637
2650
  #-----------------------------------------------------
@@ -2639,7 +2652,7 @@ class Rods
2639
2652
  unless (row)
2640
2653
  die("getCellsAndIndicesFor: internal error: Could not extract parent-row of textNode with #{content}")
2641
2654
  end
2642
- rowIndex=getIndexOfElement(row)
2655
+ rowIndex=getIndex(row)
2643
2656
  result[i][:cell]=cell
2644
2657
  result[i][:row]=rowIndex
2645
2658
  result[i][:col]=colIndex
@@ -2651,32 +2664,42 @@ class Rods
2651
2664
  end
2652
2665
  ##########################################################################
2653
2666
  # internal: Wrapper for
2654
- # getIndexOrNumberOfSiblings(node,NUMBER)
2667
+ # getIndexAndOrNumber(node,NUMBER)
2655
2668
  #-------------------------------------------------------------------------
2656
2669
  def getNumberOfSiblings(node)
2657
- return getIndexOrNumberOfSiblings(node,NUMBER)
2670
+ return getIndexAndOrNumber(node,NUMBER)
2658
2671
  end
2659
2672
  ##########################################################################
2660
2673
  # internal: Wrapper for
2661
- # getIndexOrNumberOfSiblings(node,INDEX)
2674
+ # getIndexAndOrNumber(node,INDEX)
2662
2675
  #-------------------------------------------------------------------------
2663
- def getIndexOfElement(node)
2664
- return getIndexOrNumberOfSiblings(node,INDEX)
2676
+ def getIndex(node)
2677
+ return getIndexAndOrNumber(node,INDEX)
2678
+ end
2679
+ ##########################################################################
2680
+ # internal: Wrapper for
2681
+ # getIndexAndOrNumber(node,BOTH)
2682
+ #-------------------------------------------------------------------------
2683
+ def getIndexAndNumber(node)
2684
+ return getIndexAndOrNumber(node,BOTH)
2665
2685
  end
2666
2686
  ##########################################################################
2667
2687
  # internal: Calculates index (in the sense of spreadsheet, NOT XML) of
2668
2688
  # given element (row, cell or column as REXML::Element) within the
2669
2689
  # corresponding parent-element (table or row) or the number of siblings
2670
- # of the same kind - depending on given flag
2690
+ # of the same kind or both - depending on the flag given.
2691
+ #
2692
+ # Cave: In case of flag 'BOTH' the method returns TWO values !
2671
2693
  #
2672
- # index=mySheet.getIndexOrNumberOfElements(row,INDEX) # -> Line-number within table
2673
- # numColumns=mySheet.getIndexOrNumberOfElements(column,NUMBER) # number of columns
2694
+ # index=getIndexAndOrNumber(row,INDEX) # -> Line-number within table
2695
+ # numColumns=getIndexAndOrNumber(column,NUMBER) # number of columns
2696
+ # index,numColumns=getIndexAndOrNumber(row,BOTH) # Line-number and total number of lines
2674
2697
  #-------------------------------------------------------------------------
2675
- def getIndexOrNumberOfSiblings(node,flag)
2676
- die("getIndexOrNumberOfSiblings: passed node '#{node}' is not a REXML::Element") \
2698
+ def getIndexAndOrNumber(node,flag)
2699
+ die("getIndexAndOrNumber: passed node '#{node}' is not a REXML::Element") \
2677
2700
  unless (node.class.to_s == "REXML::Element")
2678
- die("getIndexOrNumberOfSiblings: internal error: invalid flag '#{flag}'") \
2679
- unless (flag == NUMBER || flag == INDEX)
2701
+ die("getIndexAndOrNumber: internal error: invalid flag '#{flag}'") \
2702
+ unless (flag == NUMBER || flag == INDEX || flag == BOTH)
2680
2703
  #--------------------------------------------------------------
2681
2704
  # Typabhaengige Vorbelegungen
2682
2705
  #--------------------------------------------------------------
@@ -2693,49 +2716,55 @@ class Rods
2693
2716
  kindOfParent="table:table"
2694
2717
  kindOfRepetition="table:number-rows-repeated"
2695
2718
  else
2696
- die("getIndexOrNumberOfSiblings: internal error: passed element '#{node}' is neither cell, nor row or column")
2719
+ die("getIndexAndOrNumber: internal error: passed element '#{node}' is neither cell, nor row or column")
2697
2720
  end
2698
2721
  #--------------------------------------------------------------
2699
2722
  # Zugehoeriges Vater-Element ermitteln
2700
2723
  #--------------------------------------------------------------
2701
2724
  parent=node.elements["ancestor::"+kindOfParent]
2702
2725
  unless (parent)
2703
- die("getIndexOrNumberOfSiblings: internal error: Could not extract parent of #{node}")
2726
+ die("getIndexAndOrNumber: internal error: Could not extract parent of #{node}")
2704
2727
  end
2705
2728
  #--------------------------------------------------------------
2706
2729
  # Index des Kind-Elements innerhalb Vater-Element oder
2707
- # Gesamtzahl der Siblings ermitteln
2730
+ # Gesamtzahl der Items ermitteln
2708
2731
  #--------------------------------------------------------------
2709
- index=0
2732
+ index=number=0
2710
2733
  parent.elements.each(kindOfSelf){ |child|
2711
- index+=1
2734
+ number+=1
2712
2735
  #-----------------------------------------------
2713
- # Bei Treffer -> Ruecksprung mit aktuellem Index
2714
- # sofern Indizierungsflag gesetzt, sonst
2715
- # verwerfen und weiterzaehlen
2736
+ # Kind-Element gefunden ? -> Index festhalten,
2737
+ # je nach Flag Ruecksprung oder weiterzaehlen
2716
2738
  #-----------------------------------------------
2717
- if(flag == INDEX && child == node)
2718
- return index
2739
+ if(child == node)
2740
+ if(flag == INDEX)
2741
+ return number
2742
+ elsif(flag == BOTH)
2743
+ index=number
2744
+ end
2719
2745
  #-----------------------------------------------
2720
2746
  # Wiederholungen zaehlen
2721
2747
  # Cave: Aktuelles Element selbst zaehlt ebenfalls als Wiederholung
2722
2748
  # => um 1 dekrementieren
2723
2749
  #-----------------------------------------------
2724
2750
  elsif(repetition=child.attributes[kindOfRepetition])
2725
- index+=repetition.to_i-1
2751
+ number+=repetition.to_i-1
2726
2752
  end
2727
2753
  }
2728
2754
  if(flag == INDEX)
2729
- die("getIndexOrNumberOfSiblings: internal error: Could not calculate index of element #{node}")
2755
+ die("getIndexAndOrNumber: internal error: Could not calculate number of element #{node}")
2756
+ elsif(flag == NUMBER)
2757
+ return number
2730
2758
  else
2731
- return index # <- hier: Letzter Index == Gesamtzahl der Siblings
2759
+ return index,number
2732
2760
  end
2733
2761
  end
2734
2762
  ##########################################################################
2735
- # internal: Inserts a new header-column before the given column thereby
2736
- # shifting existing column-header-entries
2763
+ # internal: Inserts a new header-column before the given header-column thereby
2764
+ # shifting existing header-columns
2737
2765
  #-------------------------------------------------------------------------
2738
- def insertColumnBefore(column)
2766
+ def insertColumnBeforeInHeader(column)
2767
+ die("insertColumnBeforeInHeader: column #{column} is not a REXML::Element") unless (column.class.to_s == "REXML::Element")
2739
2768
  newColumn=createColumn(1)
2740
2769
  column.previous_sibling=newColumn
2741
2770
  #-----------------------------------------
@@ -2749,11 +2778,218 @@ class Rods
2749
2778
  return newColumn
2750
2779
  end
2751
2780
  ##########################################################################
2781
+ # Delets the cell to the right of the given cell
2782
+ #
2783
+ # cell=mySheet.writeGetCell(4,7,"date","16.01.2011")
2784
+ # mySheet.deleteCellAfter(cell)
2785
+ #-------------------------------------------------------------------------
2786
+ def deleteCellAfter(cell)
2787
+ die("deleteCellAfter: cell #{cell} is not a REXML::Element") unless (cell.class.to_s == "REXML::Element")
2788
+ #--------------------------------------------------------
2789
+ # Entweder Wiederholungsattribut der aktuellen Zelle
2790
+ # dekrementieren oder ggf. Wiederholungsattribut der
2791
+ # Folgezelle dekrementieren oder selbige loeschen
2792
+ #--------------------------------------------------------
2793
+ repetitions=cell.attributes["table:number-columns-repeated"]
2794
+ if(repetitions && repetitions.to_i > 1)
2795
+ cell.attributes["table:number-columns-repeated"]=(repetitions.to_i-1).to_s
2796
+ else
2797
+ nextCell=cell.next_sibling
2798
+ die("deleteCellAfter: cell is already last cell in row") unless (nextCell)
2799
+ nextRepetitions=nextCell.attributes["table:number-columns-repeated"]
2800
+ if(nextRepetitions && nextRepetitions.to_i > 1)
2801
+ nextCell.attributes["table:number-columns-repeated"]=(nextRepetitions.to_i-1).to_s
2802
+ else
2803
+ row=cell.elements["ancestor::table:table-row"]
2804
+ unless (row)
2805
+ die("deleteCellAfter: internal error: Could not extract parent-row of cell #{cell}")
2806
+ end
2807
+ row.elements.delete(nextCell)
2808
+ end
2809
+ end
2810
+ end
2811
+ ##########################################################################
2812
+ # Delets the row below the given row
2813
+ #
2814
+ # row=mySheet.getRow(11)
2815
+ # mySheet.deleteRowBelow(row)
2816
+ #-------------------------------------------------------------------------
2817
+ def deleteRowBelow(row)
2818
+ die("deleteRowBelow: row #{row} is not a REXML::Element") unless (row.class.to_s == "REXML::Element")
2819
+ #--------------------------------------------------------
2820
+ # Entweder Wiederholungsattribut der aktuellen Zeile
2821
+ # dekrementieren oder ggf. Wiederholungsattribut der
2822
+ # Folgezeile dekrementieren oder selbige loeschen
2823
+ #--------------------------------------------------------
2824
+ repetitions=row.attributes["table:number-rows-repeated"]
2825
+ if(repetitions && repetitions.to_i > 1)
2826
+ row.attributes["table:number-rows-repeated"]=(repetitions.to_i-1).to_s
2827
+ else
2828
+ nextRow=row.next_sibling
2829
+ die("deleteRowBelow: row #{row} is already last row in table") unless (nextRow)
2830
+ nextRepetitions=nextRow.attributes["table:number-rows-repeated"]
2831
+ if(nextRepetitions && nextRepetitions.to_i > 1)
2832
+ nextRow.attributes["table:number-rows-repeated"]=(nextRepetitions.to_i-1).to_s
2833
+ else
2834
+ table=row.elements["ancestor::table:table"]
2835
+ unless (table)
2836
+ die("deleteRowBelow: internal error: Could not extract parent-table of row #{row}")
2837
+ end
2838
+ table.elements.delete(nextRow)
2839
+ end
2840
+ end
2841
+ end
2842
+ ##########################################################################
2843
+ # Delets the cell at the given index in the given row
2844
+ #
2845
+ # row=mySheet.getRow(8)
2846
+ # mySheet.deleteCell(row,9)
2847
+ #-------------------------------------------------------------------------
2848
+ def deleteCellFromRow(row,colInd)
2849
+ die("deleteCell: row #{row} is not a REXML::Element") unless (row.class.to_s == "REXML::Element")
2850
+ die("deleteCell: index #{colInd} is not a Fixnum/Integer") unless (colInd.class.to_s == "Fixnum")
2851
+ die("deleteCell: invalid index #{colInd}") unless (colInd > 0)
2852
+ cell=getCellFromRow(row,colInd+1)
2853
+ deleteCellBefore(cell)
2854
+ end
2855
+ ##########################################################################
2856
+ # Delets the given cell.
2857
+ #
2858
+ # 'cell' is a REXML::Element as returned by getCell(cellInd).
2859
+ #
2860
+ # startCell=mySheet.getCell(34,1)
2861
+ # while(cell=mySheet.getNextExistentCell(startCell))
2862
+ # mySheet.deleteCell2(cell)
2863
+ # end
2864
+ #-------------------------------------------------------------------------
2865
+ def deleteCell2(cell)
2866
+ die("deleteCell2: cell #{cell} is not a REXML::Element") unless (cell.class.to_s == "REXML::Element")
2867
+ #-------------------------------------------------------------------
2868
+ # Entweder Wiederholungszahl dekrementieren oder Zelle loeschen
2869
+ #-------------------------------------------------------------------
2870
+ repetitions=cell.attributes["table:number-columuns-repeated"]
2871
+ if(repetitions && repetitions.to_i > 1)
2872
+ cell.attributes["table:number-columns-repeated"]=(repetitions.to_i-1).to_s
2873
+ tell("deleteCell2: decrementing empty cells")
2874
+ else
2875
+ row=cell.elements["ancestor::table:table-row"]
2876
+ unless (row)
2877
+ die("deleteCell2: internal error: Could not extract parent-row of cell #{cell}")
2878
+ end
2879
+ row.elements.delete(cell)
2880
+ tell("deleteCell2: deleting non-empty cell")
2881
+ end
2882
+ end
2883
+ ##########################################################################
2884
+ # Delets the given row.
2885
+ #
2886
+ # 'row' is a REXML::Element as returned by getRow(rowInd).
2887
+ #
2888
+ # startRow=mySheet.getRow(12)
2889
+ # while(row=mySheet.getNextExistentRow(startRow))
2890
+ # mySheet.deleteRow2(row)
2891
+ # end
2892
+ #-------------------------------------------------------------------------
2893
+ def deleteRow2(row)
2894
+ die("deleteRow2: row #{row} is not a REXML::Element") unless (row.class.to_s == "REXML::Element")
2895
+ #-------------------------------------------------------------------
2896
+ # Entweder Wiederholungszahl dekrementieren oder Zeile loeschen
2897
+ #-------------------------------------------------------------------
2898
+ repetitions=row.attributes["table:number-rows-repeated"]
2899
+ if(repetitions && repetitions.to_i > 1)
2900
+ row.attributes["table:number-rows-repeated"]=(repetitions.to_i-1).to_s
2901
+ tell("deleteRow2: decrementing empty rows")
2902
+ else
2903
+ table=row.elements["ancestor::table:table"]
2904
+ unless (table)
2905
+ die("deleteRow2: internal error: Could not extract parent-table of row #{row}")
2906
+ end
2907
+ table.elements.delete(row)
2908
+ tell("deleteRow2: deleting non-empty row")
2909
+ end
2910
+ end
2911
+ ##########################################################################
2912
+ # Delets the row at the given index
2913
+ #
2914
+ # mySheet.deleteRow(7)
2915
+ #-------------------------------------------------------------------------
2916
+ def deleteRow(rowInd)
2917
+ die("deleteRow: index #{rowInd} is not a Fixnum/Integer") unless (rowInd.class.to_s == "Fixnum")
2918
+ die("deleteRow: invalid index #{rowInd}") unless (rowInd > 0)
2919
+ row=getRow(rowInd+1)
2920
+ deleteRowAbove(row)
2921
+ end
2922
+ ##########################################################################
2923
+ # Delets the cell at the given indices
2924
+ #
2925
+ # mySheet.deleteCell(7,9)
2926
+ #-------------------------------------------------------------------------
2927
+ def deleteCell(rowInd,colInd)
2928
+ die("deleteCell: index #{rowInd} is not a Fixnum/Integer") unless (rowInd.class.to_s == "Fixnum")
2929
+ die("deleteCell: invalid index #{rowInd}") unless (rowInd > 0)
2930
+ die("deleteCell: index #{colInd} is not a Fixnum/Integer") unless (colInd.class.to_s == "Fixnum")
2931
+ die("deleteCell: invalid index #{colInd}") unless (colInd > 0)
2932
+ tell("deleteCell: deleting cell at #{rowInd}:#{colInd}")
2933
+ row=getRow(rowInd)
2934
+ deleteCellFromRow(row,colInd)
2935
+ end
2936
+ ##########################################################################
2937
+ # Delets the row above the given row
2938
+ #
2939
+ # row=mySheet.getRow(5)
2940
+ # mySheet.deleteRowAbove(row)
2941
+ #-------------------------------------------------------------------------
2942
+ def deleteRowAbove(row)
2943
+ die("deleteRowAbove: row #{row} is not a REXML::Element") unless (row.class.to_s == "REXML::Element")
2944
+ #--------------------------------------------------------
2945
+ # Entweder Wiederholungsattribut der vorherigen Zeile
2946
+ # dekrementieren oder selbige loeschen
2947
+ #--------------------------------------------------------
2948
+ previousRow=row.previous_sibling
2949
+ die("deleteRowAbove: row is already first row in row") unless (previousRow)
2950
+ previousRepetitions=previousRow.attributes["table:number-rows-repeated"]
2951
+ if(previousRepetitions && previousRepetitions.to_i > 1)
2952
+ previousRow.attributes["table:number-rows-repeated"]=(previousRepetitions.to_i-1).to_s
2953
+ else
2954
+ table=row.elements["ancestor::table:table"]
2955
+ unless (table)
2956
+ die("deleteRowAbove: internal error: Could not extract parent-table of row #{row}")
2957
+ end
2958
+ table.elements.delete(previousRow)
2959
+ end
2960
+ end
2961
+ ##########################################################################
2962
+ # Delets the cell to the left of the given cell
2963
+ #
2964
+ # cell=mySheet.writeGetCell(4,7,"formula:currency","=A1+B2")
2965
+ # mySheet.deleteCellBefore(cell)
2966
+ #-------------------------------------------------------------------------
2967
+ def deleteCellBefore(cell)
2968
+ die("deleteCellBefore: cell #{cell} is not a REXML::Element") unless (cell.class.to_s == "REXML::Element")
2969
+ #--------------------------------------------------------
2970
+ # Entweder Wiederholungsattribut der vorherigen Zelle
2971
+ # dekrementieren oder selbige loeschen
2972
+ #--------------------------------------------------------
2973
+ previousCell=cell.previous_sibling
2974
+ die("deleteCellBefore: cell is already first cell in row") unless (previousCell)
2975
+ previousRepetitions=previousCell.attributes["table:number-columns-repeated"]
2976
+ if(previousRepetitions && previousRepetitions.to_i > 1)
2977
+ previousCell.attributes["table:number-columns-repeated"]=(previousRepetitions.to_i-1).to_s
2978
+ else
2979
+ row=cell.elements["ancestor::table:table-row"]
2980
+ unless (row)
2981
+ die("deleteCellBefore: internal error: Could not extract parent-row of cell #{cell}")
2982
+ end
2983
+ row.elements.delete(previousCell)
2984
+ end
2985
+ end
2986
+ ##########################################################################
2752
2987
  # Inserts a new cell before the given cell thereby shifting existing cells
2753
2988
  # cell=mySheet.getCell(5,1)
2754
2989
  # mySheet.insertCellBefore(cell) # adds cell at beginning of row 5
2755
2990
  #-------------------------------------------------------------------------
2756
2991
  def insertCellBefore(cell)
2992
+ die("insertCellBefore: cell #{cell} is not a REXML::Element") unless (cell.class.to_s == "REXML::Element")
2757
2993
  newCell=createCell(1)
2758
2994
  cell.previous_sibling=newCell
2759
2995
  #-----------------------------------------
@@ -2773,6 +3009,7 @@ class Rods
2773
3009
  # mySheet.insertCellAfter(cell)
2774
3010
  #-------------------------------------------------------------------------
2775
3011
  def insertCellAfter(cell)
3012
+ die("insertCellAfter: cell #{cell} is not a REXML::Element") unless (cell.class.to_s == "REXML::Element")
2776
3013
  newCell=createCell(1)
2777
3014
  cell.next_sibling=newCell
2778
3015
  #-----------------------------------------------------------------------
@@ -2795,6 +3032,46 @@ class Rods
2795
3032
  return newCell
2796
3033
  end
2797
3034
  ##########################################################################
3035
+ # Inserts and returns a cell at the given index in the given row,
3036
+ # thereby shifting existing cells.
3037
+ #
3038
+ # row=mySheet.getRow(5)
3039
+ # cell=mySheet.insertCellFromRow(row,17)
3040
+ #-------------------------------------------------------------------------
3041
+ def insertCellFromRow(row,colInd)
3042
+ die("insertCell: row #{row} is not a REXML::Element") unless (row.class.to_s == "REXML::Element")
3043
+ die("insertCell: index #{colInd} is not a Fixnum/Integer") unless (colInd.class.to_s == "Fixnum")
3044
+ die("insertCell: invalid index #{colInd}") unless (colInd > 0)
3045
+ tell("insertCell: inserting new cell in column:#{colInd}")
3046
+ cell=getCellFromRow(row,colInd)
3047
+ return insertCellBefore(cell)
3048
+ end
3049
+ ##########################################################################
3050
+ # Inserts and returns a cell at the given index, thereby shifting existing cells.
3051
+ #
3052
+ # cell=mySheet.insertCell(4,17)
3053
+ #-------------------------------------------------------------------------
3054
+ def insertCell(rowInd,colInd)
3055
+ die("insertCell: index #{rowInd} is not a Fixnum/Integer") unless (rowInd.class.to_s == "Fixnum")
3056
+ die("insertCell: invalid index #{rowInd}") unless (rowInd > 0)
3057
+ die("insertCell: index #{colInd} is not a Fixnum/Integer") unless (colInd.class.to_s == "Fixnum")
3058
+ die("insertCell: invalid index #{colInd}") unless (colInd > 0)
3059
+ tell("insertCell: inserting new cell at #{rowInd}:#{colInd}")
3060
+ cell=getCell(rowInd,colInd)
3061
+ return insertCellBefore(cell)
3062
+ end
3063
+ ##########################################################################
3064
+ # Inserts and returns a row at the given index, thereby shifting existing rows
3065
+ # row=mySheet.insertRow(1) # inserts row above former row 1
3066
+ #-------------------------------------------------------------------------
3067
+ def insertRow(rowInd)
3068
+ die("insertRow: invalid rowInd #{rowInd}") unless (rowInd > 0)
3069
+ die("insertRow: rowInd #{rowInd} is not a Fixnum/Integer") unless (rowInd.class.to_s == "Fixnum")
3070
+ tell("insertRow: inserting new row")
3071
+ row=getRow(rowInd)
3072
+ return insertRowAbove(row)
3073
+ end
3074
+ ##########################################################################
2798
3075
  # Inserts a new row above the given row thereby shifting existing rows
2799
3076
  # row=mySheet.getRow(1)
2800
3077
  # mySheet.insertRowAbove(row)
@@ -2823,31 +3100,70 @@ class Rods
2823
3100
  return newRow
2824
3101
  end
2825
3102
  ##########################################################################
3103
+ # Deletes the column at the given index
3104
+ #
3105
+ # mySheet.deleteColumn(8)
3106
+ #-------------------------------------------------------------------------
3107
+ def deleteColumn(colInd)
3108
+ die("deleteColumn: index #{colInd} is not a Fixnum/Integer") unless (colInd.class.to_s == "Fixnum")
3109
+ die("deleteColumn: invalid index #{colInd}") unless (colInd > 0)
3110
+ currentWidth=@tables[@currentTableName][WIDTH]
3111
+ die("deleteColumn: column-index #{colInd} is outside valid range/current table width") if (colInd > currentWidth)
3112
+ #-------------------------------------------------------------------
3113
+ # Entweder Wiederholungsattribut der fraglichen Spalte dekrementieren
3114
+ # oder selbige loeschen
3115
+ #-------------------------------------------------------------------
3116
+ currentTable=@tables[@currentTableName][NODE]
3117
+ column=getChildByIndex(currentTable,COLUMN,colInd)
3118
+ repetitions=column.attributes["table:number-columns-repeated"]
3119
+ if(repetitions && repetitions.to_i > 1)
3120
+ column.attributes["table:number-columns-repeated"]=(repetitions.to_i-1).to_s
3121
+ else
3122
+ table=column.elements["ancestor::table:table"]
3123
+ unless (table)
3124
+ die("deleteColumn: internal error: Could not extract parent-table of column #{column}")
3125
+ end
3126
+ table.elements.delete(column)
3127
+ end
3128
+ #-----------------------------------------------
3129
+ # Fuer alle existierenden Zeilen neue Zelle an
3130
+ # Spaltenposition einfuegen und dabei implizit
3131
+ # Tabellenbreite aktualisieren
3132
+ #-----------------------------------------------
3133
+ row=getRow(1)
3134
+ deleteCellFromRow(row,colInd)
3135
+ i=1
3136
+ while(row=getNextExistentRow(row)) # fuer alle Zeilen ab der zweiten
3137
+ deleteCellFromRow(row,colInd)
3138
+ i+=1
3139
+ end
3140
+ end
3141
+ ##########################################################################
2826
3142
  # Inserts a column at the given index, thereby shifting existing columns
2827
3143
  # mySheet.insertColumn(1) # inserts column before former column 1
2828
3144
  #-------------------------------------------------------------------------
2829
- def insertColumn(index)
2830
- die("insertColumn: invalid index #{index}") unless (index > 0)
2831
- die("insertColumn: index #{index} is not a Fixnum/Integer") unless (index.class.to_s == "Fixnum")
3145
+ def insertColumn(colInd)
3146
+ die("insertColumn: index #{colInd} is not a Fixnum/Integer") unless (colInd.class.to_s == "Fixnum")
3147
+ die("insertColumn: invalid index #{colInd}") unless (colInd > 0)
2832
3148
  tell("insertColumn: inserting new column")
2833
3149
  currentTable=@tables[@currentTableName][NODE]
2834
3150
  #-----------------------------------------------
2835
3151
  # Neuer Spalteneintrag im Header mit impliziter
2836
3152
  # Aktualisierung der Tabellenbreite
2837
3153
  #-----------------------------------------------
2838
- column=getChildByIndex(currentTable,COLUMN,index)
2839
- insertColumnBefore(column)
3154
+ column=getChildByIndex(currentTable,COLUMN,colInd)
3155
+ insertColumnBeforeInHeader(column)
2840
3156
  #-----------------------------------------------
2841
3157
  # Fuer alle existierenden Zeilen neue Zelle an
2842
3158
  # Spaltenposition einfuegen und dabei implizit
2843
3159
  # Tabellenbreite aktualisieren
2844
3160
  #-----------------------------------------------
2845
3161
  row=getRow(1)
2846
- cell=getChildByIndex(row,CELL,index)
3162
+ cell=getChildByIndex(row,CELL,colInd)
2847
3163
  insertCellBefore(cell)
2848
3164
  i=1
2849
3165
  while(row=getNextExistentRow(row)) # fuer alle Zeilen ab der zweiten
2850
- cell=getChildByIndex(row,CELL,index)
3166
+ cell=getChildByIndex(row,CELL,colInd)
2851
3167
  insertCellBefore(cell)
2852
3168
  i+=1
2853
3169
  end
@@ -2856,12 +3172,12 @@ class Rods
2856
3172
  # internal: returns cell at index if existent, nil otherwise
2857
3173
  # row=getRowIfExists(4)
2858
3174
  # if(row)
2859
- # cell=getCellIfExists(row,7)
3175
+ # cell=getCellFromRowIfExists(row,7)
2860
3176
  # unless(cell) .....
2861
3177
  # end
2862
3178
  #-------------------------------------------------------------------------
2863
- def getCellIfExists(row,index)
2864
- return getElementIfExists(row,CELL,index)
3179
+ def getCellFromRowIfExists(row,colInd)
3180
+ return getElementIfExists(row,CELL,colInd)
2865
3181
  end
2866
3182
  ##########################################################################
2867
3183
  # internal: returns row at index if existent, nil otherwise
@@ -2869,9 +3185,9 @@ class Rods
2869
3185
  # ........
2870
3186
  # end
2871
3187
  #-------------------------------------------------------------------------
2872
- def getRowIfExists(index)
3188
+ def getRowIfExists(rowInd)
2873
3189
  currentTable=@tables[@currentTableName][NODE]
2874
- return getElementIfExists(currentTable,ROW,index)
3190
+ return getElementIfExists(currentTable,ROW,rowInd)
2875
3191
  end
2876
3192
  ##########################################################################
2877
3193
  # internal: examines, whether element of given type (row, cell, column) and index
@@ -2949,14 +3265,17 @@ class Rods
2949
3265
  :setStyle, :printOfficeStyles, :printAutoStyles, :getNextExistentRow, :getPreviousExistentRow,
2950
3266
  :getNextExistentCell, :getPreviousExistentCell, :insertTableAfter, :insertTableBefore,
2951
3267
  :writeComment, :save, :saveAs, :initialize, :writeText, :getCellsAndIndicesFor,
2952
- :insertRowBelow, :insertRowAbove, :insertCellBefore, :insertCellAfter, :insertColumn
3268
+ :insertRowBelow, :insertRowAbove, :insertCellBefore, :insertCellAfter, :insertColumn,
3269
+ :insertRow, :insertCell, :insertCellFromRow, :deleteCellBefore, :deleteCellAfter,
3270
+ :deleteCell, :deleteCellFromRow, :deleteRowAbove, :deleteRowBelow, :deleteRow,
3271
+ :deleteColumn, :deleteRow2, :deleteCell2
2953
3272
 
2954
3273
  private :tell, :die, :createCell, :createRow, :getChildByIndex, :createElement, :setRepetition, :initHousekeeping,
2955
3274
  :getTableWidth, :padTables, :padRow, :time2TimeVal, :percent2PercentVal, :date2DateVal,
2956
- :finalize, :init, :normalizeText, :getColor, :normStyleHash, :getStyle, :getIndexOfElement,
2957
- :getNumberOfSiblings, :getIndexOrNumberOfSiblings, :createColumn,
3275
+ :finalize, :init, :normalizeText, :getColor, :normStyleHash, :getStyle, :getIndex,
3276
+ :getNumberOfSiblings, :getIndexAndOrNumber, :createColumn,
2958
3277
  :getAppropriateStyle, :checkStyleAttributes, :insertStyleAttributes, :cloneNode,
2959
3278
  :writeStyle, :writeStyleXml, :style2Hash, :writeDefaultStyles, :writeXml,
2960
3279
  :internalizeFormula, :getColorPalette, :open, :printStyles, :insertTableBeforeAfter,
2961
- :insertColumnBefore, :getElementIfExists, :getRowIfExists, :getCellIfExists
3280
+ :insertColumnBeforeInHeader, :getElementIfExists, :getRowIfExists, :getCellFromRowIfExists
2962
3281
  end # Klassenende
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{rods}
5
- s.version = "0.8.1"
5
+ s.version = "0.9.0"
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"]
9
- s.date = %q{2011-01-13}
9
+ s.date = %q{2011-01-17}
10
10
  s.description = %q{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 ;-)}
11
11
  s.email = %q{rods.ruby@online.de}
12
12
  s.extra_rdoc_files = ["README", "lib/rods.rb"]
@@ -15,10 +15,11 @@ 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.4.2}
18
+ s.rubygems_version = %q{1.3.7}
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
22
23
  s.specification_version = 3
23
24
 
24
25
  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: 61
5
- prerelease:
4
+ hash: 59
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 8
9
- - 1
10
- version: 0.8.1
8
+ - 9
9
+ - 0
10
+ version: 0.9.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dr. Heinz Breinlinger
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-13 00:00:00 +01:00
18
+ date: 2011-01-17 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -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.4.2
73
+ rubygems_version: 1.3.7
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