excel_to_code 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/README +41 -0
  2. data/bin/excel_to_c +63 -0
  3. data/bin/excel_to_ruby +9 -0
  4. data/src/commands.rb +2 -0
  5. data/src/commands/excel_to_c.rb +858 -0
  6. data/src/commands/excel_to_ruby.rb +620 -0
  7. data/src/compile.rb +2 -0
  8. data/src/compile/c.rb +5 -0
  9. data/src/compile/c/compile_to_c.rb +62 -0
  10. data/src/compile/c/compile_to_c_header.rb +26 -0
  11. data/src/compile/c/compile_to_c_unit_test.rb +42 -0
  12. data/src/compile/c/excel_to_c_runtime.c +2029 -0
  13. data/src/compile/c/map_formulae_to_c.rb +184 -0
  14. data/src/compile/c/map_sheet_names_to_c_names.rb +19 -0
  15. data/src/compile/c/map_values_to_c.rb +85 -0
  16. data/src/compile/c/map_values_to_c_structs.rb +37 -0
  17. data/src/compile/ruby.rb +3 -0
  18. data/src/compile/ruby/compile_to_ruby.rb +33 -0
  19. data/src/compile/ruby/compile_to_ruby_unit_test.rb +28 -0
  20. data/src/compile/ruby/excel_to_ruby_runtime.rb +1 -0
  21. data/src/compile/ruby/map_formulae_to_ruby.rb +95 -0
  22. data/src/compile/ruby/map_sheet_names_to_ruby_names.rb +19 -0
  23. data/src/compile/ruby/map_values_to_ruby.rb +65 -0
  24. data/src/excel.rb +5 -0
  25. data/src/excel/area.rb +93 -0
  26. data/src/excel/excel_functions.rb +84 -0
  27. data/src/excel/excel_functions/abs.rb +14 -0
  28. data/src/excel/excel_functions/add.rb +18 -0
  29. data/src/excel/excel_functions/and.rb +30 -0
  30. data/src/excel/excel_functions/apply_to_range.rb +17 -0
  31. data/src/excel/excel_functions/average.rb +12 -0
  32. data/src/excel/excel_functions/choose.rb +18 -0
  33. data/src/excel/excel_functions/cosh.rb +9 -0
  34. data/src/excel/excel_functions/count.rb +9 -0
  35. data/src/excel/excel_functions/counta.rb +8 -0
  36. data/src/excel/excel_functions/divide.rb +23 -0
  37. data/src/excel/excel_functions/excel_equal.rb +20 -0
  38. data/src/excel/excel_functions/excel_if.rb +8 -0
  39. data/src/excel/excel_functions/excel_match.rb +51 -0
  40. data/src/excel/excel_functions/find.rb +39 -0
  41. data/src/excel/excel_functions/iferror.rb +10 -0
  42. data/src/excel/excel_functions/index.rb +48 -0
  43. data/src/excel/excel_functions/left.rb +12 -0
  44. data/src/excel/excel_functions/less_than.rb +26 -0
  45. data/src/excel/excel_functions/less_than_or_equal.rb +26 -0
  46. data/src/excel/excel_functions/max.rb +12 -0
  47. data/src/excel/excel_functions/min.rb +12 -0
  48. data/src/excel/excel_functions/mod.rb +15 -0
  49. data/src/excel/excel_functions/more_than.rb +26 -0
  50. data/src/excel/excel_functions/more_than_or_equal.rb +26 -0
  51. data/src/excel/excel_functions/multiply.rb +24 -0
  52. data/src/excel/excel_functions/negative.rb +12 -0
  53. data/src/excel/excel_functions/not_equal.rb +19 -0
  54. data/src/excel/excel_functions/number_argument.rb +30 -0
  55. data/src/excel/excel_functions/pi.rb +7 -0
  56. data/src/excel/excel_functions/pmt.rb +16 -0
  57. data/src/excel/excel_functions/power.rb +18 -0
  58. data/src/excel/excel_functions/round.rb +13 -0
  59. data/src/excel/excel_functions/rounddown.rb +14 -0
  60. data/src/excel/excel_functions/roundup.rb +17 -0
  61. data/src/excel/excel_functions/string_join.rb +19 -0
  62. data/src/excel/excel_functions/subtotal.rb +13 -0
  63. data/src/excel/excel_functions/subtract.rb +18 -0
  64. data/src/excel/excel_functions/sum.rb +8 -0
  65. data/src/excel/excel_functions/sumif.rb +7 -0
  66. data/src/excel/excel_functions/sumifs.rb +74 -0
  67. data/src/excel/excel_functions/sumproduct.rb +32 -0
  68. data/src/excel/excel_functions/vlookup.rb +49 -0
  69. data/src/excel/formula_peg.rb +238 -0
  70. data/src/excel/formula_peg.txt +45 -0
  71. data/src/excel/reference.rb +56 -0
  72. data/src/excel/table.rb +108 -0
  73. data/src/excel_to_code.rb +7 -0
  74. data/src/extract.rb +13 -0
  75. data/src/extract/check_for_unknown_functions.rb +20 -0
  76. data/src/extract/extract_array_formulae.rb +23 -0
  77. data/src/extract/extract_formulae.rb +36 -0
  78. data/src/extract/extract_named_references.rb +38 -0
  79. data/src/extract/extract_relationships.rb +10 -0
  80. data/src/extract/extract_shared_formulae.rb +23 -0
  81. data/src/extract/extract_shared_strings.rb +20 -0
  82. data/src/extract/extract_simple_formulae.rb +18 -0
  83. data/src/extract/extract_table.rb +24 -0
  84. data/src/extract/extract_values.rb +29 -0
  85. data/src/extract/extract_worksheet_dimensions.rb +11 -0
  86. data/src/extract/extract_worksheet_names.rb +10 -0
  87. data/src/extract/extract_worksheet_table_relationships.rb +10 -0
  88. data/src/extract/simple_extract_from_xml.rb +19 -0
  89. data/src/rewrite.rb +10 -0
  90. data/src/rewrite/ast_copy_formula.rb +42 -0
  91. data/src/rewrite/ast_expand_array_formulae.rb +180 -0
  92. data/src/rewrite/rewrite_array_formulae.rb +71 -0
  93. data/src/rewrite/rewrite_array_formulae_to_arrays.rb +18 -0
  94. data/src/rewrite/rewrite_cell_references_to_include_sheet.rb +56 -0
  95. data/src/rewrite/rewrite_formulae_to_ast.rb +24 -0
  96. data/src/rewrite/rewrite_merge_formulae_and_values.rb +18 -0
  97. data/src/rewrite/rewrite_relationship_id_to_filename.rb +22 -0
  98. data/src/rewrite/rewrite_shared_formulae.rb +38 -0
  99. data/src/rewrite/rewrite_values_to_ast.rb +28 -0
  100. data/src/rewrite/rewrite_whole_row_column_references_to_areas.rb +90 -0
  101. data/src/rewrite/rewrite_worksheet_names.rb +20 -0
  102. data/src/simplify.rb +16 -0
  103. data/src/simplify/count_formula_references.rb +58 -0
  104. data/src/simplify/identify_dependencies.rb +56 -0
  105. data/src/simplify/identify_repeated_formula_elements.rb +37 -0
  106. data/src/simplify/inline_formulae.rb +77 -0
  107. data/src/simplify/map_formulae_to_values.rb +157 -0
  108. data/src/simplify/remove_cells.rb +18 -0
  109. data/src/simplify/replace_arrays_with_single_cells.rb +27 -0
  110. data/src/simplify/replace_blanks.rb +58 -0
  111. data/src/simplify/replace_common_elements_in_formulae.rb +19 -0
  112. data/src/simplify/replace_formulae_with_calculated_values.rb +21 -0
  113. data/src/simplify/replace_indirects_with_references.rb +44 -0
  114. data/src/simplify/replace_named_references.rb +82 -0
  115. data/src/simplify/replace_ranges_with_array_literals.rb +54 -0
  116. data/src/simplify/replace_shared_strings.rb +49 -0
  117. data/src/simplify/replace_table_references.rb +71 -0
  118. data/src/simplify/replace_values_with_constants.rb +47 -0
  119. data/src/simplify/simplify_arithmetic.rb +54 -0
  120. data/src/util.rb +2 -0
  121. data/src/util/not_supported_exception.rb +2 -0
  122. data/src/util/try.rb +9 -0
  123. metadata +207 -0
@@ -0,0 +1,45 @@
1
+ formula := space? expression+
2
+ expression = string_join | comparison | arithmetic | thing
3
+ thing = function | array | brackets | any_reference | string | percentage | number | boolean | prefix | named_reference
4
+ argument = expression | null
5
+ function := /[A-Z]+/ `'(' space argument? (space `',' space argument)* space `')'
6
+ brackets := `'(' space expression+ space `')'
7
+ array := `'{' space row ( space `';' space row )* space `'}'
8
+ row := basic_type ( space `',' space basic_type )*
9
+ basic_type = string | percentage | number | boolean
10
+ string_join := (arithmetic | thing) (space `"&" space (arithmetic | thing))+
11
+ arithmetic := thing (space operator space thing)+
12
+ comparison := (arithmetic | thing) space comparator space (arithmetic | thing)
13
+ comparator := '>=' | '<=' | '<>' | '>' | '<' | '='
14
+ string := `'"' /(""|[^"])*/ `'"'
15
+ any_reference = external_reference | any_internal_reference
16
+ any_internal_reference = table_reference | local_table_reference | sheet_reference | sheetless_reference
17
+ percentage := /[-+]?[0-9]+\.?[0-9]*/ `'%'
18
+ number := /[-+]?[0-9]+\.?[0-9]*([eE][-+]?[0-9]+)?/
19
+ operator := '+' | '-' | '/' | '*' | '^'
20
+ external_reference := /\[\d+\]!?/ any_internal_reference
21
+ table_reference := table_name `'[' (range_structured_reference | complex_structured_reference | simple_structured_reference) `']'
22
+ local_table_reference := `'[' (range_structured_reference | complex_structured_reference | overly_structured_reference | simple_structured_reference) `']'
23
+ table_name = /[.a-zA-Z0-9_]+/
24
+ range_structured_reference = /\[[^\u005d]*\],\[[^\u005d]*\]:\[[^\u005d]*\]/
25
+ complex_structured_reference = /\[[^\u005d]*\],\[[^\u005d]*\]/
26
+ overly_structured_reference = `'[' simple_structured_reference `']'
27
+ simple_structured_reference = /[^\u005d]*/
28
+ named_reference := /[#a-zA-Z][\w_.!]+/
29
+ sheet_reference := (single_quoted_string | /[a-zA-Z0-9][\w_.]+/) `'!' (sheetless_reference | named_reference)
30
+ single_quoted_string = `"'" /[^']*/ `"'"
31
+ sheetless_reference = column_range | row_range | area | cell
32
+ column_range := column `':' column
33
+ row_range := row_number `':' row_number
34
+ area := reference `':' reference
35
+ cell := reference
36
+ row_number = /\$?\d+/
37
+ column = /\$?[A-Za-z]{1,3}/
38
+ reference = /\$?[A-Za-z]{1,3}\$?[0-9]+(?![0-9A-Za-z_])/
39
+ boolean = boolean_true | boolean_false
40
+ boolean_true := `'TRUE'
41
+ boolean_false := `'FALSE'
42
+ prefix := /[-+]/ thing
43
+ space = `/[ \n]*/
44
+ null := &','
45
+
@@ -0,0 +1,56 @@
1
+ class Reference < String
2
+
3
+ # This is so that we only have one instance for a given reference
4
+ @@references_for_text ||= Hash.new do |hash,text|
5
+ hash[text] = reference = Reference.new(text)
6
+ reference
7
+ end
8
+
9
+ # This is so that we only have one instance of a given reference specified by its variables
10
+ def Reference.for(text)
11
+ @@references_for_text[text]
12
+ end
13
+
14
+ # This caches the calculation for turning column letters (e.g., AAB) into column numbers (e.g., 127)
15
+ @@column_number_for_column ||= Hash.new do |hash,letters|
16
+ number = letters.downcase.each_byte.to_a.reverse.each.with_index.inject(0) do |memo,byte_with_index,c|
17
+ memo + ((byte_with_index.first - 96) * (26**byte_with_index.last))
18
+ end
19
+ hash[letters] = number
20
+ @@column_letters_for_column_number[number] = letters.upcase
21
+ number
22
+ end
23
+
24
+ # This caches the calculation for turning column numbers (e.g., 127) into column letters (e.g., AAB)
25
+ @@column_letters_for_column_number ||= Hash.new do |hash,number|
26
+ letters = (number-1).to_i.to_s(26)
27
+ letters = (letters[0...-1].tr('1-9a-z','abcdefghijklmnopqrstuvwxyz') + letters[-1,1].tr('0-9a-z','abcdefghijklmnopqrstuvwxyz')).gsub('a0','z').gsub(/([b-z])0/) { $1.tr('b-z','a-y')+"z" }
28
+ letters.upcase!
29
+ hash[number] = letters
30
+ @@column_number_for_column[letters] = number
31
+ letters
32
+ end
33
+
34
+ attr_reader :excel_row_number, :excel_column_number, :excel_column, :excel_row
35
+
36
+ def calculate_excel_variables
37
+ return if @excel_variables_calculated
38
+ self =~ /(\$)?([A-Za-z]{1,3})(\$)?([0-9]+)/
39
+ @excel_fixed_column, @excel_column, @excel_fixed_row, @excel_row = $1, $2, $3, $4
40
+ @excel_row_number = @excel_row.to_i
41
+ @excel_column_number = @@column_number_for_column[@excel_column]
42
+ @excel_variables_calculated = true
43
+ end
44
+
45
+ def offset(rows,columns)
46
+ calculate_excel_variables
47
+ new_column = @excel_fixed_column ? @excel_column : @@column_letters_for_column_number[@excel_column_number + columns]
48
+ new_row = @excel_fixed_row ? @excel_row : @excel_row_number + rows
49
+ Reference.new([@excel_fixed_column,new_column,@excel_fixed_row,new_row].join)
50
+ end
51
+
52
+ def unfix
53
+ gsub("$","")
54
+ end
55
+
56
+ end
@@ -0,0 +1,108 @@
1
+ require_relative '../excel'
2
+ require_relative '../util'
3
+
4
+ class Table
5
+
6
+ attr_accessor :name
7
+
8
+ def initialize(name,worksheet,reference,number_of_total_rows,*column_name_array)
9
+ @name, @worksheet, @area, @number_of_total_rows, @column_name_array = name, worksheet, Area.for(reference), number_of_total_rows.to_i, column_name_array.map { |c| c.strip.downcase }
10
+ @area.calculate_excel_variables
11
+ @data_area = Area.for("#{@area.excel_start.offset(1,0)}:#{@area.excel_finish.offset(-@number_of_total_rows,0)}")
12
+ end
13
+
14
+ def reference_for(table_name,structured_reference,calling_worksheet,calling_cell)
15
+ raise NotSupportedException.new("Local table reference not supported in #{structured_reference.inspect}") unless table_name
16
+ case structured_reference
17
+ when /\[#Headers\],\[(.*?)\]:\[(.*?)\]/io
18
+ column_number_start = @column_name_array.find_index($1.strip.downcase)
19
+ column_number_finish = @column_name_array.find_index($2.strip.downcase)
20
+ return ref_error unless column_number_start && column_number_finish
21
+ ast_for_area @area.excel_start.offset(0,column_number_start), @area.excel_start.offset(0,column_number_finish)
22
+ when /\[#Totals\],\[(.*?)\]:\[(.*?)\]/io
23
+ column_number_start = @column_name_array.find_index($1.strip.downcase)
24
+ column_number_finish = @column_name_array.find_index($2.strip.downcase)
25
+ return ref_error unless column_number_start && column_number_finish
26
+ ast_for_area @area.excel_start.offset(@area.height,column_number_start), @area.excel_start.offset(@area.height,column_number_finish)
27
+ when /\[#This Row\],\[(.*?)\]:\[(.*?)\]/io
28
+ r = Reference.for(calling_cell)
29
+ r.calculate_excel_variables
30
+ row = r.excel_row_number
31
+ column_number_start = @column_name_array.find_index($1.strip.downcase)
32
+ column_number_finish = @column_name_array.find_index($2.strip.downcase)
33
+ return ref_error unless column_number_start && column_number_finish
34
+ ast_for_area @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number_start), @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number_finish)
35
+ when /\[#Headers\],\[(.*?)\]/io
36
+ column_number = @column_name_array.find_index($1.strip.downcase)
37
+ return ref_error unless column_number
38
+ ast_for_cell @area.excel_start.offset(0,column_number)
39
+ when /\[#Totals\],\[(.*?)\]/io
40
+ column_number = @column_name_array.find_index($1.strip.downcase)
41
+ return ref_error unless column_number
42
+ ast_for_cell @area.excel_start.offset(@area.height,column_number)
43
+ when /\[#This Row\],\[(.*?)\]/io
44
+ r = Reference.for(calling_cell)
45
+ r.calculate_excel_variables
46
+ row = r.excel_row_number
47
+ column_number = @column_name_array.find_index($1.strip.downcase)
48
+ return ref_error unless column_number
49
+ ast_for_cell @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number)
50
+ when /#Headers/io
51
+ if calling_worksheet == @worksheet && @data_area.includes?(calling_cell)
52
+ r = Reference.for(calling_cell)
53
+ r.calculate_excel_variables
54
+ ast_for_cell "#{r.excel_column}#{@area.excel_start.excel_row_number}"
55
+ else
56
+ ast_for_area @area.excel_start.offset(0,0), @area.excel_start.offset(0,@area.width)
57
+ end
58
+ when /#Totals/io
59
+ if calling_worksheet == @worksheet && @data_area.includes?(calling_cell)
60
+ r = Reference.for(calling_cell)
61
+ r.calculate_excel_variables
62
+ ast_for_cell "#{r.excel_column}#{@area.excel_finish.excel_row_number}"
63
+ else
64
+ ast_for_area @area.excel_start.offset(@area.height,0), @area.excel_start.offset(@area.height,@area.width)
65
+ end
66
+ when /#Data/io, ""
67
+ ast_for_area @data_area.excel_start, @data_area.excel_finish
68
+ when /#All/io, ""
69
+ ast_for_area @area.excel_start, @area.excel_finish
70
+ when /#This Row/io
71
+ r = Reference.for(calling_cell)
72
+ r.calculate_excel_variables
73
+ row = r.excel_row_number
74
+ ast_for_area "#{@area.excel_start.excel_column}#{row}", "#{@area.excel_finish.excel_column}#{row}"
75
+ else
76
+ if calling_worksheet == @worksheet && @data_area.includes?(calling_cell)
77
+ r = Reference.for(calling_cell)
78
+ r.calculate_excel_variables
79
+ row = r.excel_row_number
80
+ column_number = @column_name_array.find_index(structured_reference.strip.downcase)
81
+ return ref_error unless column_number
82
+ ast_for_cell @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number)
83
+ else
84
+ column_number = @column_name_array.find_index(structured_reference.strip.downcase)
85
+ return ref_error unless column_number
86
+ ast_for_area @area.excel_start.offset(1,column_number), @area.excel_start.offset(@area.height - @number_of_total_rows,column_number)
87
+ end
88
+ end
89
+ end
90
+
91
+ def ast_for_area(start,finish)
92
+ [:sheet_reference,@worksheet,[:area,start,finish]]
93
+ end
94
+
95
+ def ast_for_cell(ref)
96
+ [:sheet_reference,@worksheet,[:cell,ref]]
97
+ end
98
+
99
+ def ref_error
100
+ [:error,"#REF!"]
101
+ end
102
+
103
+ def includes?(sheet,reference)
104
+ return false unless @worksheet == sheet
105
+ @area.includes?(reference)
106
+ end
107
+
108
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'commands'
2
+ require_relative 'compile'
3
+ require_relative 'excel'
4
+ require_relative 'extract'
5
+ require_relative 'rewrite'
6
+ require_relative 'simplify'
7
+ require_relative 'util'
data/src/extract.rb ADDED
@@ -0,0 +1,13 @@
1
+ require_relative 'extract/check_for_unknown_functions'
2
+ require_relative "extract/extract_array_formulae"
3
+ require_relative "extract/extract_formulae"
4
+ require_relative "extract/extract_relationships"
5
+ require_relative "extract/extract_shared_formulae"
6
+ require_relative "extract/extract_shared_strings"
7
+ require_relative "extract/extract_simple_formulae"
8
+ require_relative "extract/extract_values"
9
+ require_relative "extract/extract_worksheet_dimensions"
10
+ require_relative "extract/extract_worksheet_names"
11
+ require_relative "extract/extract_named_references"
12
+ require_relative "extract/extract_worksheet_table_relationships"
13
+ require_relative "extract/extract_table"
@@ -0,0 +1,20 @@
1
+ require_relative '../compile/ruby/map_formulae_to_ruby'
2
+
3
+ class CheckForUnknownFunctions
4
+
5
+ attr_accessor :settable
6
+
7
+ def self.rewrite(*args)
8
+ self.new.rewrite(*args)
9
+ end
10
+
11
+ def check(input,output)
12
+ self.settable ||= lambda { |ref| false }
13
+ input.lines do |line|
14
+ line.scan(/\[:function, "(.*?)"/).each do |match|
15
+ output.puts $1 unless MapFormulaeToRuby::FUNCTIONS.has_key?($1)
16
+ end
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'extract_formulae'
2
+
3
+ class ExtractArrayFormulae < ExtractFormulae
4
+
5
+ attr_accessor :array_range
6
+
7
+ def start_formula(type,attributes)
8
+ return unless type == 'array' && attributes.assoc('ref')
9
+ @array_range = attributes.assoc('ref').last
10
+ @parsing = true
11
+ end
12
+
13
+ def write_formula
14
+ return false if @formula.empty?
15
+ output.write @ref
16
+ output.write "\t"
17
+ output.write @array_range
18
+ output.write "\t"
19
+ output.write @formula.join
20
+ output.write "\n"
21
+ end
22
+
23
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'simple_extract_from_xml'
2
+
3
+ class ExtractFormulae < SimpleExtractFromXML
4
+
5
+ attr_accessor :ref, :formula
6
+
7
+ def start_element(name,attributes)
8
+ if name == 'c'
9
+ @ref = attributes.assoc('r').last
10
+ elsif name == "f"
11
+ type = attributes.assoc('t')
12
+ @formula = []
13
+ start_formula( type && type.last, attributes)
14
+ end
15
+ end
16
+
17
+ def start_formula(type,attributes)
18
+ # Should be overriden in sub classes
19
+ end
20
+
21
+ def write_formula
22
+ # Should be overriden in sub classes
23
+ end
24
+
25
+ def end_element(name)
26
+ return unless parsing && name == "f"
27
+ self.parsing = false
28
+ write_formula
29
+ end
30
+
31
+ def characters(string)
32
+ return unless parsing
33
+ @formula.push(string)
34
+ end
35
+
36
+ end
@@ -0,0 +1,38 @@
1
+ require_relative 'simple_extract_from_xml'
2
+
3
+ class ExtractNamedReferences < SimpleExtractFromXML
4
+
5
+ attr_accessor :sheet_names
6
+
7
+ def initialize
8
+ super
9
+ @sheet_names = []
10
+ end
11
+
12
+ def start_element(name,attributes)
13
+ if name == "sheet"
14
+ sheet_names << attributes.assoc('name').last
15
+ elsif name == "definedName"
16
+ @parsing = true
17
+ sheet = attributes.assoc('localSheetId')
18
+ if sheet
19
+ output.write sheet_names[sheet.last.to_i]
20
+ end
21
+ output.write "\t"
22
+ output.write attributes.assoc('name').last
23
+ output.write "\t"
24
+ end
25
+ end
26
+
27
+ def end_element(name)
28
+ return unless name == "definedName"
29
+ self.parsing = false
30
+ output.putc "\n"
31
+ end
32
+
33
+ def characters(string)
34
+ return unless parsing
35
+ output.write string
36
+ end
37
+
38
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'simple_extract_from_xml'
2
+
3
+ class ExtractRelationships < SimpleExtractFromXML
4
+
5
+ def start_element(name,attributes)
6
+ return false unless name == "Relationship"
7
+ output.puts "#{attributes.assoc('Id').last}\t#{attributes.assoc('Target').last}"
8
+ end
9
+
10
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'extract_formulae'
2
+
3
+ class ExtractSharedFormulae < ExtractFormulae
4
+
5
+ attr_accessor :shared_range
6
+
7
+ def start_formula(type,attributes)
8
+ return unless type == 'shared' && attributes.assoc('ref')
9
+ @shared_range = attributes.assoc('ref').last
10
+ @parsing = true
11
+ end
12
+
13
+ def write_formula
14
+ return if @formula.empty?
15
+ output.write @ref
16
+ output.write "\t"
17
+ output.write @shared_range
18
+ output.write "\t"
19
+ output.write @formula.join
20
+ output.write "\n"
21
+ end
22
+
23
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'simple_extract_from_xml'
2
+
3
+ class ExtractSharedStrings < SimpleExtractFromXML
4
+
5
+ def start_element(name,attributes)
6
+ self.parsing = true if name == "si"
7
+ end
8
+
9
+ def end_element(name)
10
+ return unless name == "si"
11
+ self.parsing = false
12
+ output.putc "\n"
13
+ end
14
+
15
+ def characters(string)
16
+ return unless parsing
17
+ output.write string.gsub("\n","")
18
+ end
19
+
20
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'extract_formulae'
2
+
3
+ class ExtractSimpleFormulae < ExtractFormulae
4
+
5
+ def start_formula(type,attributes)
6
+ return if type
7
+ @parsing = true
8
+ end
9
+
10
+ def write_formula
11
+ return if @formula.empty?
12
+ output.write @ref
13
+ output.write "\t"
14
+ output.write @formula.join
15
+ output.write "\n"
16
+ end
17
+
18
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'simple_extract_from_xml'
2
+
3
+ class ExtractTable < SimpleExtractFromXML
4
+
5
+ attr_accessor :worksheet_name
6
+
7
+ def initialize(worksheet_name = nil)
8
+ super()
9
+ @worksheet_name = worksheet_name
10
+ end
11
+
12
+ def start_element(name,attributes)
13
+ if name == "table"
14
+ output.write "#{attributes.assoc('displayName').last}\t#{@worksheet_name}\t#{attributes.assoc('ref').last}\t#{attributes.assoc('totalsRowCount').try(:last) || 0}"
15
+ elsif name == "tableColumn"
16
+ output.write "\t#{attributes.assoc('name').last}"
17
+ end
18
+ end
19
+
20
+ def end_element(name)
21
+ return unless name == "table"
22
+ output.putc "\n"
23
+ end
24
+ end