ttb-spreadsheet 0.6.5.8

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 (65) hide show
  1. data/GUIDE.txt +267 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +18 -0
  4. data/History.txt +365 -0
  5. data/LICENSE.txt +619 -0
  6. data/Manifest.txt +62 -0
  7. data/README.txt +107 -0
  8. data/Rakefile +0 -0
  9. data/bin/xlsopcodes +18 -0
  10. data/lib/parseexcel.rb +27 -0
  11. data/lib/parseexcel/parseexcel.rb +75 -0
  12. data/lib/parseexcel/parser.rb +11 -0
  13. data/lib/spreadsheet.rb +79 -0
  14. data/lib/spreadsheet/column.rb +71 -0
  15. data/lib/spreadsheet/compatibility.rb +23 -0
  16. data/lib/spreadsheet/datatypes.rb +106 -0
  17. data/lib/spreadsheet/encodings.rb +57 -0
  18. data/lib/spreadsheet/excel.rb +88 -0
  19. data/lib/spreadsheet/excel/error.rb +26 -0
  20. data/lib/spreadsheet/excel/internals.rb +365 -0
  21. data/lib/spreadsheet/excel/internals/biff5.rb +17 -0
  22. data/lib/spreadsheet/excel/internals/biff8.rb +19 -0
  23. data/lib/spreadsheet/excel/offset.rb +41 -0
  24. data/lib/spreadsheet/excel/reader.rb +1173 -0
  25. data/lib/spreadsheet/excel/reader/biff5.rb +22 -0
  26. data/lib/spreadsheet/excel/reader/biff8.rb +199 -0
  27. data/lib/spreadsheet/excel/row.rb +92 -0
  28. data/lib/spreadsheet/excel/sst_entry.rb +46 -0
  29. data/lib/spreadsheet/excel/workbook.rb +80 -0
  30. data/lib/spreadsheet/excel/worksheet.rb +100 -0
  31. data/lib/spreadsheet/excel/writer.rb +1 -0
  32. data/lib/spreadsheet/excel/writer/biff8.rb +75 -0
  33. data/lib/spreadsheet/excel/writer/format.rb +253 -0
  34. data/lib/spreadsheet/excel/writer/workbook.rb +690 -0
  35. data/lib/spreadsheet/excel/writer/worksheet.rb +891 -0
  36. data/lib/spreadsheet/font.rb +92 -0
  37. data/lib/spreadsheet/format.rb +177 -0
  38. data/lib/spreadsheet/formula.rb +9 -0
  39. data/lib/spreadsheet/helpers.rb +11 -0
  40. data/lib/spreadsheet/link.rb +43 -0
  41. data/lib/spreadsheet/row.rb +132 -0
  42. data/lib/spreadsheet/workbook.rb +126 -0
  43. data/lib/spreadsheet/worksheet.rb +287 -0
  44. data/lib/spreadsheet/writer.rb +30 -0
  45. data/spreadsheet.gemspec +20 -0
  46. data/test/data/test_changes.xls +0 -0
  47. data/test/data/test_copy.xls +0 -0
  48. data/test/data/test_datetime.xls +0 -0
  49. data/test/data/test_empty.xls +0 -0
  50. data/test/data/test_formula.xls +0 -0
  51. data/test/data/test_long_sst_record.xls +0 -0
  52. data/test/data/test_missing_row.xls +0 -0
  53. data/test/data/test_version_excel5.xls +0 -0
  54. data/test/data/test_version_excel95.xls +0 -0
  55. data/test/data/test_version_excel97.xls +0 -0
  56. data/test/excel/row.rb +35 -0
  57. data/test/excel/writer/workbook.rb +23 -0
  58. data/test/excel/writer/worksheet.rb +24 -0
  59. data/test/font.rb +163 -0
  60. data/test/integration.rb +1311 -0
  61. data/test/row.rb +33 -0
  62. data/test/suite.rb +17 -0
  63. data/test/workbook.rb +29 -0
  64. data/test/worksheet.rb +80 -0
  65. metadata +151 -0
@@ -0,0 +1,23 @@
1
+ module Spreadsheet
2
+ module Compatibility
3
+ ##
4
+ # One of the most incisive changes in terms of meta-programming in Ruby 1.9
5
+ # is the switch from representing instance-variable names as Strings to
6
+ # presenting them as Symbols. ivar_name provides compatibility.
7
+ if RUBY_VERSION >= '1.9'
8
+ def ivar_name symbol
9
+ :"@#{symbol}"
10
+ end
11
+ def method_name symbol
12
+ symbol.to_sym
13
+ end
14
+ else
15
+ def ivar_name symbol
16
+ "@#{symbol}"
17
+ end
18
+ def method_name symbol
19
+ symbol.to_s
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,106 @@
1
+ require 'spreadsheet/compatibility'
2
+
3
+ module Spreadsheet
4
+ ##
5
+ # This module defines convenience-methods for the definition of Spreadsheet
6
+ # attributes (boolean, colors and enumerations)
7
+ module Datatypes
8
+ include Compatibility
9
+ def Datatypes.append_features mod
10
+ super
11
+ mod.module_eval do
12
+ class << self
13
+ ##
14
+ # Valid colors for color attributes.
15
+ COLORS = [ :builtin_black, :builtin_white, :builtin_red, :builtin_green,
16
+ :builtin_blue, :builtin_yellow, :builtin_magenta, :builtin_cyan,
17
+ :text, :border, :pattern_bg, :dialog_bg, :chart_text, :chart_bg,
18
+ :chart_border, :tooltip_bg, :tooltip_text, :aqua,
19
+ :navajowhite, :pastel_purple, :lightskyblue,:light_cyan,
20
+ :black, :blue, :cyan, :brown, :fuchsia, :gray, :grey, :green,
21
+ :lime, :magenta, :navy, :orange, :purple, :red, :silver, :white,
22
+ :yellow ]
23
+ ##
24
+ # Define instance methods to read and write boolean attributes.
25
+ def boolean *args
26
+ args.each do |key|
27
+ define_method key do
28
+ name = ivar_name key
29
+ !!(instance_variable_get(name) if instance_variables.include?(name))
30
+ end
31
+ define_method "#{key}?" do
32
+ send key
33
+ end
34
+ define_method "#{key}=" do |arg|
35
+ arg = false if arg == 0
36
+ instance_variable_set(ivar_name(key), !!arg)
37
+ end
38
+ define_method "#{key}!" do
39
+ send "#{key}=", true
40
+ end
41
+ end
42
+ end
43
+ ##
44
+ # Define instance methods to read and write color attributes.
45
+ # For valid colors see COLORS
46
+ def colors *args
47
+ args.each do |key|
48
+ attr_reader key
49
+ define_method "#{key}=" do |name|
50
+ name = name.to_s.downcase.to_sym
51
+ if COLORS.include?(name)
52
+ instance_variable_set ivar_name(key), name
53
+ else
54
+ raise ArgumentError, "unknown color '#{name}'"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ ##
60
+ # Define instance methods to read and write enumeration attributes.
61
+ # * The first argument designates the attribute name.
62
+ # * The second argument designates the default value.
63
+ # * All subsequent attributes are possible values.
64
+ # * If the last attribute is a Hash, each value in the Hash designates
65
+ # aliases for the corresponding key.
66
+ def enum key, *values
67
+ aliases = {}
68
+ if values.last.is_a? Hash
69
+ values.pop.each do |value, synonyms|
70
+ if synonyms.is_a? Array
71
+ synonyms.each do |synonym| aliases.store synonym, value end
72
+ else
73
+ aliases.store synonyms, value
74
+ end
75
+ end
76
+ end
77
+ values.each do |value|
78
+ aliases.store value, value
79
+ end
80
+ define_method key do
81
+ name = ivar_name key
82
+ value = instance_variable_get(name) if instance_variables.include? name
83
+ value || values.first
84
+ end
85
+ define_method "#{key}=" do |arg|
86
+ if arg
87
+ arg = aliases.fetch arg do
88
+ aliases.fetch arg.to_s.downcase.gsub(/[ \-]/, '_').to_sym, arg
89
+ end
90
+ if values.any? do |val| val === arg end
91
+ instance_variable_set(ivar_name(key), arg)
92
+ else
93
+ valid = values.collect do |val| val.inspect end.join ', '
94
+ raise ArgumentError,
95
+ "Invalid value '#{arg.inspect}' for #{key}. Valid values are: #{valid}"
96
+ end
97
+ else
98
+ instance_variable_set ivar_name(key), values.first
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # Spreadsheet::Encoding -- spreadheet -- 07.09.2011 -- mhatakeyama@ywesee.com
4
+ # Spreadsheet::Encoding -- spreadheet -- 03.07.2009 -- hwyss@ywesee.com
5
+
6
+ module Spreadsheet
7
+ ##
8
+ # Methods for Encoding-conversions. You should not need to use any of these.
9
+ module Encodings
10
+ if RUBY_VERSION >= '1.9'
11
+ def client string, internal='UTF-16LE'
12
+ string = string.dup
13
+ string.force_encoding internal
14
+ string.encode Spreadsheet.client_encoding
15
+ end
16
+ def internal string, client=Spreadsheet.client_encoding
17
+ string = string.dup
18
+ string.force_encoding client
19
+ string.encode('UTF-16LE').force_encoding('ASCII-8BIT')
20
+ end
21
+ def utf8 string, client=Spreadsheet.client_encoding
22
+ string = string.dup
23
+ string.force_encoding client
24
+ string.encode('UTF-8')
25
+ end
26
+ else
27
+ require 'iconv'
28
+ @@iconvs = {}
29
+ def client string, internal='UTF-16LE'
30
+ string = string.dup
31
+ key = [Spreadsheet.client_encoding, internal]
32
+ iconv = @@iconvs[key] ||= Iconv.new(Spreadsheet.client_encoding, internal)
33
+ iconv.iconv string
34
+ end
35
+ def internal string, client=Spreadsheet.client_encoding
36
+ string = string.dup
37
+ key = ['UTF-16LE', client]
38
+ iconv = @@iconvs[key] ||= Iconv.new('UTF-16LE', client)
39
+ iconv.iconv string
40
+ end
41
+ def utf8 string, client=Spreadsheet.client_encoding
42
+ string = string.dup
43
+ key = ['UTF-8', client]
44
+ iconv = @@iconvs[key] ||= Iconv.new('UTF-8', client)
45
+ iconv.iconv string
46
+ end
47
+ end
48
+ rescue LoadError
49
+ warn "You don't have Iconv support compiled in your Ruby. Spreadsheet may not work as expected"
50
+ def client string, internal='UTF-16LE'
51
+ string.delete "\0"
52
+ end
53
+ def internal string, internal='UTF-16LE'
54
+ string.split('').zip(Array.new(string.size, 0.chr)).join
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,88 @@
1
+ require 'spreadsheet'
2
+
3
+ warn <<-EOS
4
+ [DEPRECATED] By requiring 'spreadsheet/excel' you are loading a Compatibility
5
+ layer which provides a drop-in replacement for Spreadsheet::Excel
6
+ versions <= 0.3.5.1. This code will be removed in Spreadsheet
7
+ version 1.0.0
8
+ EOS
9
+ ##
10
+ # Spreadsheet::Excel Compatibility Layer.
11
+ # Drop-in replacement for Spreadsheet::Excel version <= 0.3.5.1
12
+ module Spreadsheet
13
+ module Excel
14
+ class ExcelCompatibleWorkbook < Workbook
15
+ def initialize file_path, *args
16
+ super *args
17
+ @file_path = file_path
18
+ end
19
+ def close
20
+ write @file_path
21
+ end
22
+ end
23
+ def Excel.new file_path
24
+ ExcelCompatibleWorkbook.new file_path
25
+ end
26
+ class Workbook
27
+ def add_worksheet name
28
+ if name.is_a? String
29
+ create_worksheet :name => name
30
+ else
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
36
+ class Worksheet
37
+ unless instance_methods.include? "new_format_column"
38
+ alias :new_format_column :format_column
39
+ def format_column column, width=nil, format=nil
40
+ if width.is_a? Format
41
+ new_format_column column, width, format
42
+ else
43
+ new_format_column column, format, :width => width
44
+ end
45
+ end
46
+ end
47
+ def write row, col, data=nil, format=nil
48
+ if data.is_a? Array
49
+ write_row row, col, data, format
50
+ else
51
+ row = row(row)
52
+ row[col] = data
53
+ row.set_format col, format
54
+ end
55
+ end
56
+ def write_column row, col, data=nil, format=nil
57
+ if data.is_a? Array
58
+ data.each do |token|
59
+ if token.is_a? Array
60
+ write_row row, col, token, format
61
+ else
62
+ write row, col, token, format
63
+ end
64
+ row += 1
65
+ end
66
+ else
67
+ write row, col, data, format
68
+ end
69
+ end
70
+ def write_row row, col, data=nil, format=nil
71
+ if data.is_a? Array
72
+ data.each do |token|
73
+ if token.is_a? Array
74
+ write_column row, col, token, format
75
+ else
76
+ write row, col, token, format
77
+ end
78
+ col += 1
79
+ end
80
+ else
81
+ write row, col, data, format
82
+ end
83
+ end
84
+ def write_url row, col, url, string=url, format=nil
85
+ row(row)[col] = Link.new url, string
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,26 @@
1
+ module Spreadsheet
2
+ module Excel
3
+ ##
4
+ # This class encapsulates Excel Error-Codes
5
+ class Error
6
+ attr_reader :code
7
+ ERROR_VALUES = {
8
+ 0x00 => '#NULL!', # Intersection of two cell ranges is empty
9
+ 0x07 => '#DIV/0!', # Division by zero
10
+ 0x0F => '#VALUE!', # Wrong type of operand
11
+ 0x17 => '#REF!', # Illegal or deleted cell reference
12
+ 0x1D => '#NAME?', # Wrong function or range name
13
+ 0x24 => '#NUM!', # Value range overflow
14
+ 0x2A => '#N/A!', # Argument or function not available
15
+ }
16
+ def initialize code
17
+ @code = code
18
+ end
19
+ ##
20
+ # The String value Excel associates with an Error code
21
+ def value
22
+ ERROR_VALUES.fetch @code, '#UNKNOWN'
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,365 @@
1
+ require 'date'
2
+
3
+ module Spreadsheet
4
+ module Excel
5
+ ##
6
+ # Binary Formats and other configurations internal to Excel. This Module is
7
+ # likely to shrink as Support for older Versions of Excel grows and more Binary
8
+ # formats are moved away from here for disambiguation.
9
+ # If you need to work with constants defined in this module and are confused by
10
+ # names like SEDOC_ROLOC, try reading them backwards. (The reason for this weird
11
+ # naming convention is that according to my ri, Ruby 1.9 renames Hash#index to
12
+ # Hash#key without backward compatibility. Since I did not want to pepper my code
13
+ # with RUBY_VERSION-checks, I settled on this strategy to make the transition to
14
+ # Ruby 1.9 as simple as possible.
15
+ module Internals
16
+ EIGHT_BYTE_DOUBLE = [0.1].pack('E').size == 8 ? 'E' : 'e'
17
+ CODEPAGES = {
18
+ 367 => "ASCII",
19
+ 437 => "IBM437", #(US)
20
+ 720 => "IBM720", #(OEM Arabic)
21
+ 737 => "IBM737", #(Greek)
22
+ 775 => "IBM775", #(Baltic)
23
+ 850 => "IBM850", #(Latin I)
24
+ 852 => "IBM852", #(Latin II (Central European))
25
+ 855 => "IBM855", #(Cyrillic)
26
+ 857 => "IBM857", #(Turkish)
27
+ 858 => "IBM858", #(Multilingual Latin I with Euro)
28
+ 860 => "IBM860", #(Portuguese)
29
+ 861 => "IBM861", #(Icelandic)
30
+ 862 => "IBM862", #(Hebrew)
31
+ 863 => "IBM863", #(Canadian (French))
32
+ 864 => "IBM864", #(Arabic)
33
+ 865 => "IBM865", #(Nordic)
34
+ 866 => "IBM866", #(Cyrillic (Russian))
35
+ 869 => "IBM869", #(Greek (Modern))
36
+ 874 => "WINDOWS-874", #(Thai)
37
+ 932 => "WINDOWS-932", #(Japanese Shift-JIS)
38
+ 936 => "WINDOWS-936", #(Chinese Simplified GBK)
39
+ 949 => "WINDOWS-949", #(Korean (Wansung))
40
+ 950 => "WINDOWS-950", #(Chinese Traditional BIG5)
41
+ 1200 => "UTF-16LE", #(BIFF8)
42
+ 1250 => "WINDOWS-1250", #(Latin II) (Central European)
43
+ 1251 => "WINDOWS-1251", #(Cyrillic)
44
+ 1252 => "WINDOWS-1252", #(Latin I) (BIFF4-BIFF7)
45
+ 1253 => "WINDOWS-1253", #(Greek)
46
+ 1254 => "WINDOWS-1254", #(Turkish)
47
+ 1255 => "WINDOWS-1255", #(Hebrew)
48
+ 1256 => "WINDOWS-1256", #(Arabic)
49
+ 1257 => "WINDOWS-1257", #(Baltic)
50
+ 1258 => "WINDOWS-1258", #(Vietnamese)
51
+ 1361 => "WINDOWS-1361", #(Korean (Johab))
52
+ 10000 => "MACINTOSH",
53
+ 32768 => "MACINTOSH",
54
+ 32769 => "WINDOWS-1252", #(Latin I) (BIFF2-BIFF3)
55
+ }
56
+ SEGAPEDOC = CODEPAGES.invert
57
+ COLOR_CODES = {
58
+ 0x0000 => :builtin_black,
59
+ 0x0001 => :builtin_white,
60
+ 0x0002 => :builtin_red,
61
+ 0x0003 => :builtin_green,
62
+ 0x0004 => :builtin_blue,
63
+ 0x0005 => :builtin_yellow,
64
+ 0x0006 => :builtin_magenta,
65
+ 0x0007 => :builtin_cyan,
66
+ 0x0008 => :black,
67
+ 0x0009 => :white,
68
+ 0x000a => :red,
69
+ 0x000b => :lime,
70
+ 0x000c => :blue,
71
+ 0x000d => :yellow,
72
+ 0x000e => :magenta,
73
+ 0x000f => :cyan,
74
+ 0x0010 => :brown,
75
+ 0x0011 => :green,
76
+ 0x0012 => :navy,
77
+ 0x0016 => :silver,
78
+ 0x0017 => :gray,
79
+ 0x0034 => :orange,
80
+ 0x0024 => :purple,
81
+ 0x0040 => :border,
82
+ 0x0041 => :pattern_bg,
83
+ 0x0043 => :dialog_bg,
84
+ 0x004d => :chart_text,
85
+ 0x004e => :chart_bg,
86
+ 0x004f => :chart_border,
87
+ 0x0050 => :tooltip_bg,
88
+ 0x0051 => :tooltip_text,
89
+ 0x002F => :navajowhite,
90
+ 0x0036 => :pastel_purple,
91
+ 0x002C => :lightskyblue,
92
+ 0x001B => :light_cyan,
93
+ 0x7fff => :text,
94
+ }
95
+ SEDOC_ROLOC = COLOR_CODES.invert.update( :aqua => 0x000f,
96
+ :fuchsia => 0x000e,
97
+ :grey => 0x0017 )
98
+ BINARY_FORMATS = {
99
+ :blank => 'v3',
100
+ :boolerr => 'v3C2',
101
+ :colinfo => 'v5x2',
102
+ :font => 'v5C3x',
103
+ :labelsst => 'v3V',
104
+ :number => "v3#{EIGHT_BYTE_DOUBLE}",
105
+ :pagesetup => "v8#{EIGHT_BYTE_DOUBLE}2v",
106
+ :rk => 'v3V',
107
+ :row => 'v4x4V',
108
+ :window2 => 'v4x2v2x4',
109
+ :xf => 'v3C4V2v',
110
+ }
111
+ # From BIFF5 on, the built-in number formats will be omitted. The built-in
112
+ # formats are dependent on the current regional settings of the operating
113
+ # system. The following table shows which number formats are used by
114
+ # default in a US-English environment. All indexes from 0 to 163 are
115
+ # reserved for built-in formats.
116
+ BUILTIN_FORMATS = { # TODO: locale support
117
+ 0 => 'GENERAL',
118
+ 1 => '0',
119
+ 2 => '0.00',
120
+ 3 => '#,##0',
121
+ 4 => '#,##0.00',
122
+ 5 => '"$"#,##0_);("$"#,##0)',
123
+ 6 => '"$"#,##0_);[Red]("$"#,##0)',
124
+ 7 => '"$"#,##0.00_);("$"#,##0.00)',
125
+ 8 => '"$"#,##0.00_);[Red]("$"#,##0.00)',
126
+ 9 => '0%',
127
+ 10 => '0.00%',
128
+ 11 => '0.00E+00',
129
+ 12 => '# ?/?',
130
+ 13 => '# ??/??',
131
+ 14 => 'M/D/YY',
132
+ 15 => 'D-MMM-YY',
133
+ 16 => 'D-MMM',
134
+ 17 => 'MMM-YY',
135
+ 18 => 'h:mm AM/PM',
136
+ 19 => 'h:mm:ss AM/PM',
137
+ 20 => 'h:mm',
138
+ 21 => 'h:mm:ss',
139
+ 22 => 'M/D/YY h:mm',
140
+ 37 => '_(#,##0_);(#,##0)',
141
+ 38 => '_(#,##0_);[Red](#,##0)',
142
+ 39 => '_(#,##0.00_);(#,##0.00)',
143
+ 40 => '_(#,##0.00_);[Red](#,##0.00)',
144
+ 41 => '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)',
145
+ 42 => '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
146
+ 43 => '_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
147
+ 44 => '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
148
+ 45 => 'mm:ss',
149
+ 46 => '[h]:mm:ss',
150
+ 47 => 'mm:ss.0',
151
+ 48 => '##0.0E+0',
152
+ 49 => '@',
153
+ }
154
+ BUILTIN_STYLES = {
155
+ 0x00 => 'Normal',
156
+ 0x01 => 'RowLevel_lv',
157
+ 0x02 => 'ColLevel_lv',
158
+ 0x03 => 'Comma',
159
+ 0x04 => 'Currency',
160
+ 0x05 => 'Percent',
161
+ 0x06 => 'Comma',
162
+ 0x07 => 'Currency',
163
+ 0x08 => 'Hyperlink',
164
+ 0x09 => 'Followed Hyperlink',
165
+ }
166
+ ESCAPEMENT_TYPES = {
167
+ 0x0001 => :superscript,
168
+ 0x0002 => :subscript,
169
+ }
170
+ SEPYT_TNEMEPACSE = ESCAPEMENT_TYPES.invert
171
+ FONT_ENCODINGS = {
172
+ 0x00 => :iso_latin1,
173
+ 0x01 => :default,
174
+ 0x02 => :symbol,
175
+ 0x4d => :apple_roman,
176
+ 0x80 => :shift_jis,
177
+ 0x81 => :korean_hangul,
178
+ 0x82 => :korean_johab,
179
+ 0x86 => :chinese_simplified,
180
+ 0x88 => :chinese_traditional,
181
+ 0xa1 => :greek,
182
+ 0xa2 => :turkish,
183
+ 0xa3 => :vietnamese,
184
+ 0xb1 => :hebrew,
185
+ 0xb2 => :arabic,
186
+ 0xba => :baltic,
187
+ 0xcc => :cyrillic,
188
+ 0xde => :thai,
189
+ 0xee => :iso_latin2,
190
+ 0xff => :oem_latin1,
191
+ }
192
+ SGNIDOCNE_TNOF = FONT_ENCODINGS.invert
193
+ FONT_FAMILIES = {
194
+ 0x01 => :roman,
195
+ 0x02 => :swiss,
196
+ 0x03 => :modern,
197
+ 0x04 => :script,
198
+ 0x05 => :decorative,
199
+ }
200
+ SEILIMAF_TNOF = FONT_FAMILIES.invert
201
+ FONT_WEIGHTS = {
202
+ :bold => 700,
203
+ :normal => 400,
204
+ }
205
+ LEAP_ERROR = Date.new 1900, 2, 28
206
+ OPCODES = {
207
+ :blank => 0x0201, # BLANK ➜ 6.7
208
+ :boolerr => 0x0205, # BOOLERR ➜ 6.10
209
+ :boundsheet => 0x0085, # ●● BOUNDSHEET ➜ 6.12
210
+ :codepage => 0x0042, # ○ CODEPAGE ➜ 6.17
211
+ :colinfo => 0x007d, # ○○ COLINFO ➜ 6.18
212
+ :continue => 0x003c, # ○ CONTINUE ➜ 6.22
213
+ :datemode => 0x0022, # ○ DATEMODE ➜ 6.25
214
+ :dbcell => 0x0a0b, # ○ DBCELL
215
+ :dimensions => 0x0200, # ● DIMENSIONS ➜ 6.31
216
+ :eof => 0x000a, # ● EOF ➜ 6.36
217
+ :font => 0x0031, # ●● FONT ➜ 6.43
218
+ :format => 0x041e, # ○○ FORMAT (Number Format) ➜ 6.45
219
+ :formula => 0x0006, # FORMULA ➜ 6.46
220
+ :hlink => 0x01b8, # HLINK ➜ 6.52 (BIFF8 only)
221
+ :label => 0x0204, # LABEL ➜ 6.59 (BIFF2-BIFF7)
222
+ :labelsst => 0x00fd, # LABELSST ➜ 6.61 (BIFF8 only)
223
+ :mulblank => 0x00be, # MULBLANK ➜ 6.64 (BIFF5-BIFF8)
224
+ :mulrk => 0x00bd, # MULRK ➜ 6.65 (BIFF5-BIFF8)
225
+ :number => 0x0203, # NUMBER ➜ 6.68
226
+ :rk => 0x027e, # RK ➜ 6.82 (BIFF3-BIFF8)
227
+ :row => 0x0208, # ● ROW ➜ 6.83
228
+ :rstring => 0x00d6, # RSTRING ➜ 6.84 (BIFF5/BIFF7)
229
+ :sst => 0x00fc, # ● SST ➜ 6.96
230
+ :string => 0x0207, # STRING ➜ 6.98
231
+ :style => 0x0293, # ●● STYLE ➜ 6.99
232
+ :xf => 0x00e0, # ●● XF ➜ 6.115
233
+ :sharedfmla => 0x04bc, # SHAREDFMLA ➜ 5.94
234
+ ########################## Unhandled Opcodes ################################
235
+ :extsst => 0x00ff, # ● EXTSST ➜ 6.40
236
+ :index => 0x020b, # ○ INDEX ➜ 5.7 (Row Blocks), ➜ 6.55
237
+ :uncalced => 0x005e, # ○ UNCALCED ➜ 6.104
238
+ ########################## ○ Calculation Settings Block ➜ 5.3
239
+ :calccount => 0x000c, # ○ CALCCOUNT ➜ 6.14
240
+ :calcmode => 0x000d, # ○ CALCMODE ➜ 6.15
241
+ :precision => 0x000e, # ○ PRECISION ➜ 6.74 (moved to Workbook Globals
242
+ # Substream in BIFF5-BIFF8)
243
+ :refmode => 0x000f, # ○ REFMODE ➜ 6.80
244
+ :delta => 0x0010, # ○ DELTA ➜ 6.30
245
+ :iteration => 0x0011, # ○ ITERATION ➜ 6.57
246
+ :saverecalc => 0x005f, # ○ SAVERECALC ➜ 6.85 (BIFF3-BIFF8 only)
247
+ ########################## ○ Workbook Protection Block ➜ 5.18
248
+ :protect => 0x0012, # ○ PROTECT
249
+ # Worksheet contents: 1 = protected (➜ 6.77)
250
+ :windowprot => 0x0019, # ○ WINDOWPROTECT Window settings: 1 = protected
251
+ # (BIFF4W only, ➜ 6.110)
252
+ :objectprot => 0x0063, # ○ OBJECTPROTECT
253
+ # Embedded objects: 1 = protected (➜ 6.69)
254
+ :scenprotect => 0x00dd, # ○ SCENPROTECT
255
+ # Scenarios: 1 = protected (BIFF5-BIFF8, ➜ 6.86)
256
+ :password => 0x0013, # ○ PASSWORD Hash value of the password;
257
+ # 0 = no password (➜ 6.72)
258
+ ########################## ○ File Protection Block ➜ 5.19
259
+ :writeprot => 0x0086, # ○ WRITEPROT File is write protected
260
+ # (BIFF3-BIFF8, ➜ 6.112), password in FILESHARING
261
+ :filepass => 0x002f, # ○ FILEPASS File is read/write-protected,
262
+ # encryption information (➜ 6.41)
263
+ :writeaccess => 0x005c, # ○ WRITEACCESS User name (BIFF3-BIFF8, ➜ 6.111)
264
+ :filesharing => 0x005b, # ○ FILESHARING File sharing options
265
+ # (BIFF3-BIFF8, ➜ 6.42)
266
+ ########################## ○ Link Table ➜ 5.10.3
267
+ # ●● SUPBOOK Block(s)
268
+ # Settings for a referenced document
269
+ :supbook => 0x01ae, # ● SUPBOOK ➜ 6.100
270
+ :externname => 0x0223, # ○○ EXTERNNAME ➜ 6.38
271
+ :xct => 0x0059, # ○○ ● XCT ➜ 6.114
272
+ :crn => 0x005a, # ●● CRN ➜ 6.24
273
+ :externsheet => 0x0017, # ● EXTERNSHEET ➜ 6.39
274
+ :name => 0x0218, # ○○ NAME ➜ 6.66
275
+ ##########################
276
+ :window1 => 0x003d, # ● WINDOW1 ➜ 6.108 (has information on
277
+ # which Spreadsheet is 'active')
278
+ :backup => 0x0040, # ○ BACKUP ➜ 6.5
279
+ :country => 0x008c, # ○ COUNTRY (Make writeable?) ➜ 6.23
280
+ :hideobj => 0x008d, # ○ HIDEOBJ ➜ 6.52
281
+ :palette => 0x0092, # ○ PALETTE ➜ 6.70
282
+ :fngroupcnt => 0x009c, # ○ FNGROUPCOUNT
283
+ :bookbool => 0x00da, # ○ BOOKBOOL ➜ 6.9
284
+ :tabid => 0x013d, # ○ TABID
285
+ :useselfs => 0x0160, # ○ USESELFS (Natural Language Formulas) ➜ 6.105
286
+ :dsf => 0x0161, # ○ DSF (Double Stream File) ➜ 6.32
287
+ :refreshall => 0x01b7, # ○ REFRESHALL
288
+ ########################## ● Worksheet View Settings Block ➜ 5.5
289
+ :window2 => 0x023e, # ● WINDOW2 ➜ 5.110
290
+ :scl => 0x00a0, # ○ SCL ➜ 5.92 (BIFF4-BIFF8 only)
291
+ :pane => 0x0041, # ○ PANE ➜ 5.75
292
+ :selection => 0x001d, # ○○ SELECTION ➜ 5.93
293
+ ########################## ○ Page Settings Block ➜ 5.4
294
+ :hpagebreaks => 0x001b, # ○ HORIZONTALPAGEBREAKS ➜ 6.54
295
+ :vpagebreaks => 0x001a, # ○ VERTICALPAGEBREAKS ➜ 6.107
296
+ :header => 0x0014, # ○ HEADER ➜ 6.51
297
+ :footer => 0x0015, # ○ FOOTER ➜ 6.44
298
+ :hcenter => 0x0083, # ○ HCENTER ➜ 6.50 (BIFF3-BIFF8 only)
299
+ :vcenter => 0x0084, # ○ VCENTER ➜ 6.106 (BIFF3-BIFF8 only)
300
+ :leftmargin => 0x0026, # ○ LEFTMARGIN ➜ 6.62
301
+ :rightmargin => 0x0027, # ○ RIGHTMARGIN ➜ 6.81
302
+ :topmargin => 0x0028, # ○ TOPMARGIN ➜ 6.103
303
+ :bottommargin => 0x0029, # ○ BOTTOMMARGIN ➜ 6.11
304
+ # ○ PLS (opcode unknown)
305
+ :pagesetup => 0x00a1, # ○ PAGESETUP ➜ 6.89 (BIFF4-BIFF8 only)
306
+ :bitmap => 0x00e9, # ○ BITMAP ➜ 6.6 (Background-Bitmap, BIFF8 only)
307
+ ##########################
308
+ :printheaders => 0x002a, # ○ PRINTHEADERS ➜ 6.76
309
+ :printgridlns => 0x002b, # ○ PRINTGRIDLINES ➜ 6.75
310
+ :gridset => 0x0082, # ○ GRIDSET ➜ 6.48
311
+ :guts => 0x0080, # ○ GUTS ➜ 6.49
312
+ :defrowheight => 0x0225, # ○ DEFAULTROWHEIGHT ➜ 6.28
313
+ :wsbool => 0x0081, # ○ WSBOOL ➜ 6.113
314
+ :defcolwidth => 0x0055, # ○ DEFCOLWIDTH ➜ 6.29
315
+ :sort => 0x0090, # ○ SORT ➜ 6.95
316
+ }
317
+ =begin ## unknown opcodes
318
+ 0x00bf, 0x00c0, 0x00c1, 0x00e1, 0x00e2, 0x00eb, 0x01af, 0x01bc
319
+ =end
320
+ SEDOCPO = OPCODES.invert
321
+ TWIPS = 20
322
+ UNDERLINE_TYPES = {
323
+ 0x0001 => :single,
324
+ 0x0002 => :double,
325
+ 0x0021 => :single_accounting,
326
+ 0x0022 => :double_accounting,
327
+ }
328
+ SEPYT_ENILREDNU = UNDERLINE_TYPES.invert
329
+ XF_H_ALIGN = {
330
+ :default => 0,
331
+ :left => 1,
332
+ :center => 2,
333
+ :right => 3,
334
+ :fill => 4,
335
+ :justify => 5,
336
+ :merge => 6,
337
+ :distributed => 7,
338
+ }
339
+ NGILA_H_FX = XF_H_ALIGN.invert
340
+ XF_TEXT_DIRECTION = {
341
+ :context => 0,
342
+ :left_to_right => 1,
343
+ :right_to_left => 2,
344
+ }
345
+ NOITCERID_TXET_FX = XF_TEXT_DIRECTION.invert
346
+ XF_V_ALIGN = {
347
+ :top => 0,
348
+ :middle => 1,
349
+ :bottom => 2,
350
+ :justify => 3,
351
+ :distributed => 4,
352
+ }
353
+ NGILA_V_FX = XF_V_ALIGN.invert
354
+ OPCODE_SIZE = 4
355
+ ROW_HEIGHT = 12.1
356
+ SST_CHUNKSIZE = 20
357
+ def binfmt key
358
+ BINARY_FORMATS[key]
359
+ end
360
+ def opcode key
361
+ OPCODES[key]
362
+ end
363
+ end
364
+ end
365
+ end