excel_to_code 0.0.1

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 (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