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,20 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def excel_equal?(a,b)
6
+ return apply_to_range(a,b) { |a,b| excel_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ case a
12
+ when String
13
+ a.downcase == b.downcase
14
+ else
15
+ a == b
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,8 @@
1
+ module ExcelFunctions
2
+
3
+ def excel_if(condition,true_value,false_value = false)
4
+ return condition if condition.is_a?(Symbol)
5
+ condition ? true_value : false_value
6
+ end
7
+
8
+ end
@@ -0,0 +1,51 @@
1
+ module ExcelFunctions
2
+
3
+ def excel_match(lookup_value,lookup_array,match_type = 0)
4
+ return lookup_value if lookup_value.is_a?(Symbol)
5
+ return lookup_array if lookup_array.is_a?(Symbol)
6
+ return match_type if match_type.is_a?(Symbol)
7
+
8
+ lookup_value ||= 0
9
+ lookup_array ||= [0]
10
+ match_type ||= 0
11
+ lookup_array = [lookup_array] unless lookup_array.is_a?(Array)
12
+ lookup_array = lookup_array.flatten
13
+
14
+ lookup_value = lookup_value.downcase if lookup_value.respond_to?(:downcase)
15
+ case match_type
16
+ when 0, 0.0, false
17
+ lookup_array.each_with_index do |item,index|
18
+ item ||= 0
19
+ item = item.downcase if item.respond_to?(:downcase)
20
+ return index+1 if lookup_value == item
21
+ end
22
+ return :na
23
+ when 1, 1.0, true
24
+ lookup_array.each_with_index do |item, index|
25
+ item ||= 0
26
+ next if lookup_value.is_a?(String) && !item.is_a?(String)
27
+ next if lookup_value.is_a?(Numeric) && !item.is_a?(Numeric)
28
+ item = item.downcase if item.respond_to?(:downcase)
29
+ if item > lookup_value
30
+ return :na if index == 0
31
+ return index
32
+ end
33
+ end
34
+ return lookup_array.to_a.size
35
+ when -1, -1.0
36
+ lookup_array.each_with_index do |item, index|
37
+ item ||= 0
38
+ next if lookup_value.is_a?(String) && !item.is_a?(String)
39
+ next if lookup_value.is_a?(Numeric) && !item.is_a?(Numeric)
40
+ item = item.downcase if item.respond_to?(:downcase)
41
+ if item < lookup_value
42
+ return :na if index == 0
43
+ return index
44
+ end
45
+ end
46
+ return lookup_array.to_a.size - 1
47
+ end
48
+ return :na
49
+ end
50
+
51
+ end
@@ -0,0 +1,39 @@
1
+ module ExcelFunctions
2
+
3
+ def find(find_text,within_text,start_number = 1)
4
+ return find_text if find_text.is_a?(Symbol)
5
+ return within_text if within_text.is_a?(Symbol)
6
+ return start_number if start_number.is_a?(Symbol)
7
+
8
+ # nils are treated as empty strings
9
+ find_text ||= ""
10
+ within_text ||= ""
11
+
12
+ # there are some cases where the start_number is remapped
13
+ case start_number
14
+ when nil; return :value
15
+ when String;
16
+ begin
17
+ start_number = Float(start_number)
18
+ rescue ArgumentError
19
+ return :value
20
+ end
21
+ when true; start_number = 1
22
+ when false; return :value
23
+ when Numeric; # ok
24
+ else; return :value
25
+ end
26
+
27
+ # edge case
28
+ return 1 if find_text == "" && within_text == "" && start_number == 1
29
+
30
+ # length check
31
+ return :value if start_number < 1
32
+ return :value if start_number > within_text.length
33
+
34
+ # Ok, lets go
35
+ result = within_text.index(find_text,start_number - 1 )
36
+ result ? result + 1 : :value
37
+ end
38
+
39
+ end
@@ -0,0 +1,10 @@
1
+ module ExcelFunctions
2
+
3
+ def iferror(value,value_if_error)
4
+ value_if_error ||= 0
5
+ return value_if_error if value.is_a?(Symbol)
6
+ return value_if_error if value.is_a?(Float) && value.nan?
7
+ value
8
+ end
9
+
10
+ end
@@ -0,0 +1,48 @@
1
+ module ExcelFunctions
2
+
3
+ def index(array, row_number, column_number = :not_specified)
4
+
5
+ return array if array.is_a?(Symbol)
6
+ return row_number if row_number.is_a?(Symbol)
7
+ return column_number if column_number.is_a?(Symbol) && column_number != :not_specified
8
+
9
+ array = [[array]] unless array.is_a?(Array)
10
+
11
+ if column_number == :not_specified
12
+ if array.length == 1 # It is a single row
13
+ index_for_row_column(array,1,row_number)
14
+ elsif array.first.length == 1 # it is a single column
15
+ index_for_row_column(array,row_number,1)
16
+ else
17
+ return :ref
18
+ end
19
+ else
20
+ if row_number == nil || row_number == 0
21
+ index_for_whole_column(array,column_number)
22
+ elsif column_number == nil || column_number == 0
23
+ index_for_whole_row(array,row_number)
24
+ else
25
+ index_for_row_column(array,row_number,column_number)
26
+ end
27
+ end
28
+ end
29
+
30
+ def index_for_row_column(array,row_number,column_number)
31
+ return :ref if row_number < 1 || row_number > array.length
32
+ row = array[row_number-1]
33
+ return :ref if column_number < 1 || column_number > row.length
34
+ row[column_number-1] || 0
35
+ end
36
+
37
+ def index_for_whole_row(array,row_number)
38
+ return :ref if row_number < 1
39
+ return :ref if row_number > array.length
40
+ [array[row_number-1]]
41
+ end
42
+
43
+ def index_for_whole_column(array,column_number)
44
+ return :ref if column_number < 1
45
+ return :ref if column_number > array[0].length
46
+ array.map { |row| [row[column_number-1]]}
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def left(string,characters = 1)
4
+ return string if string.is_a?(Symbol)
5
+ return characters if characters.is_a?(Symbol)
6
+ return nil if string == nil || characters == nil
7
+ string = "TRUE" if string == true
8
+ string = "FALSE" if string == false
9
+ string.to_s.slice(0,characters)
10
+ end
11
+
12
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def less_than?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| less_than?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase < b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a < b
21
+ else
22
+ a < b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def less_than_or_equal?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| less_than_or_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase <= b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a <= b
21
+ else
22
+ a <= b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def max(*args)
4
+ args = args.flatten
5
+ error = args.find {|a| a.is_a?(Symbol)}
6
+ return error if error
7
+ args.delete_if { |a| !a.is_a?(Numeric) }
8
+ return 0 if args.empty?
9
+ args.max
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def min(*args)
4
+ args = args.flatten
5
+ error = args.find {|a| a.is_a?(Symbol)}
6
+ return error if error
7
+ args.delete_if { |a| !a.is_a?(Numeric) }
8
+ return 0 if args.empty?
9
+ args.min
10
+ end
11
+
12
+ end
@@ -0,0 +1,15 @@
1
+ module ExcelFunctions
2
+
3
+ def mod(a,b)
4
+ a = number_argument(a)
5
+ b = number_argument(b)
6
+
7
+ return a if a.is_a?(Symbol)
8
+ return b if b.is_a?(Symbol)
9
+
10
+ return :div0 if b == 0
11
+
12
+ a % b
13
+ end
14
+
15
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def more_than?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| more_than?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase > b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a > b
21
+ else
22
+ a > b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def more_than_or_equal?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| more_than_or_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase >= b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a >= b
21
+ else
22
+ a >= b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'number_argument'
2
+ require_relative 'apply_to_range'
3
+
4
+ module ExcelFunctions
5
+
6
+ def multiply(a,b)
7
+ begin
8
+ # return apply_to_range(a,b) { |a,b| multiply(a,b) } if a.is_a?(Array) || b.is_a?(Array)
9
+
10
+ a = number_argument(a)
11
+ b = number_argument(b)
12
+
13
+ return a if a.is_a?(Symbol)
14
+ return b if b.is_a?(Symbol)
15
+
16
+ a * b
17
+
18
+ rescue Error => e
19
+ print e.backtrace.join('\n')
20
+ raise
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def negative(a)
4
+ a = number_argument(a)
5
+
6
+ return a if a.is_a?(Symbol)
7
+
8
+ -a
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def not_equal?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| not_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ case a
12
+ when String
13
+ a.downcase != b.downcase
14
+ else
15
+ a != b
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,30 @@
1
+ module ExcelFunctions
2
+
3
+ # This is a support function for mapping arguments that are numbers to numeric values
4
+ # deals with the fact that in Excel "2.14" == 2.14, TRUE == 1, FALSE == 0 and nil == 0
5
+ def number_argument(a)
6
+ case a
7
+ when Symbol
8
+ return a
9
+ when String
10
+ begin
11
+ return Float(a)
12
+ rescue ArgumentError
13
+ return :value
14
+ end
15
+ when nil
16
+ return 0
17
+ when true
18
+ return 1
19
+ when false
20
+ return 0
21
+ when Numeric
22
+ return a
23
+ when Array
24
+ return a[0][0]
25
+ else
26
+ return :value
27
+ end
28
+ end
29
+
30
+ end