rods 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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