ruby-spreadsheet 0.6.5

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 (64) hide show
  1. data/.document +5 -0
  2. data/GUIDE.txt +267 -0
  3. data/Gemfile +12 -0
  4. data/Gemfile.lock +20 -0
  5. data/History.txt +307 -0
  6. data/LICENSE.txt +619 -0
  7. data/README.txt +91 -0
  8. data/Rakefile +53 -0
  9. data/VERSION +1 -0
  10. data/bin/xlsopcodes +18 -0
  11. data/lib/parseexcel.rb +27 -0
  12. data/lib/parseexcel/parseexcel.rb +75 -0
  13. data/lib/parseexcel/parser.rb +11 -0
  14. data/lib/spreadsheet.rb +79 -0
  15. data/lib/spreadsheet/column.rb +71 -0
  16. data/lib/spreadsheet/compatibility.rb +23 -0
  17. data/lib/spreadsheet/datatypes.rb +110 -0
  18. data/lib/spreadsheet/encodings.rb +46 -0
  19. data/lib/spreadsheet/excel.rb +88 -0
  20. data/lib/spreadsheet/excel/error.rb +26 -0
  21. data/lib/spreadsheet/excel/internals.rb +386 -0
  22. data/lib/spreadsheet/excel/internals/biff5.rb +17 -0
  23. data/lib/spreadsheet/excel/internals/biff8.rb +19 -0
  24. data/lib/spreadsheet/excel/offset.rb +41 -0
  25. data/lib/spreadsheet/excel/reader.rb +1173 -0
  26. data/lib/spreadsheet/excel/reader/biff5.rb +22 -0
  27. data/lib/spreadsheet/excel/reader/biff8.rb +193 -0
  28. data/lib/spreadsheet/excel/row.rb +92 -0
  29. data/lib/spreadsheet/excel/sst_entry.rb +46 -0
  30. data/lib/spreadsheet/excel/workbook.rb +80 -0
  31. data/lib/spreadsheet/excel/worksheet.rb +100 -0
  32. data/lib/spreadsheet/excel/writer.rb +1 -0
  33. data/lib/spreadsheet/excel/writer/biff8.rb +75 -0
  34. data/lib/spreadsheet/excel/writer/format.rb +253 -0
  35. data/lib/spreadsheet/excel/writer/workbook.rb +652 -0
  36. data/lib/spreadsheet/excel/writer/worksheet.rb +948 -0
  37. data/lib/spreadsheet/font.rb +92 -0
  38. data/lib/spreadsheet/format.rb +177 -0
  39. data/lib/spreadsheet/formula.rb +9 -0
  40. data/lib/spreadsheet/helpers.rb +11 -0
  41. data/lib/spreadsheet/link.rb +43 -0
  42. data/lib/spreadsheet/row.rb +132 -0
  43. data/lib/spreadsheet/workbook.rb +120 -0
  44. data/lib/spreadsheet/worksheet.rb +279 -0
  45. data/lib/spreadsheet/writer.rb +30 -0
  46. data/ruby-spreadsheet.gemspec +126 -0
  47. data/test/data/test_changes.xls +0 -0
  48. data/test/data/test_copy.xls +0 -0
  49. data/test/data/test_datetime.xls +0 -0
  50. data/test/data/test_empty.xls +0 -0
  51. data/test/data/test_formula.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/worksheet.rb +23 -0
  58. data/test/font.rb +163 -0
  59. data/test/integration.rb +1281 -0
  60. data/test/row.rb +33 -0
  61. data/test/suite.rb +14 -0
  62. data/test/workbook.rb +21 -0
  63. data/test/worksheet.rb +80 -0
  64. metadata +203 -0
@@ -0,0 +1,110 @@
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
+ :black, :white, :olive, :teal, :violet, :burgundy, :cream,
18
+ :light_cyan, :dark_purple, :dark_blue, :lavender, :red, :lime,
19
+ :blue, :yellow, :magenta, :cyan, :brown, :green, :navy, :silver,
20
+ :gray, :orange, :purple, :sky_blue, :sea_green, :canary_yellow,
21
+ :cornflower, :pink, :fuchsia, :peach, :medium_blue, :turquoise,
22
+ :yellow_green, :yellow_orange, :burnt_orange, :red_orange,
23
+ :dark_violet, :dark_gray, :midnight_blue, :border, :pattern_bg,
24
+ :dialog_bg, :chart_text, :chart_bg, :chart_border, :tooltip_bg,
25
+ :tooltip_text, :text, :aqua, :grey]
26
+
27
+ ##
28
+ # Define instance methods to read and write boolean attributes.
29
+ def boolean *args
30
+ args.each do |key|
31
+ define_method key do
32
+ name = ivar_name key
33
+ !!(instance_variable_get(name) if instance_variables.include?(name))
34
+ end
35
+ define_method "#{key}?" do
36
+ send key
37
+ end
38
+ define_method "#{key}=" do |arg|
39
+ arg = false if arg == 0
40
+ instance_variable_set(ivar_name(key), !!arg)
41
+ end
42
+ define_method "#{key}!" do
43
+ send "#{key}=", true
44
+ end
45
+ end
46
+ end
47
+ ##
48
+ # Define instance methods to read and write color attributes.
49
+ # For valid colors see COLORS
50
+ def colors *args
51
+ args.each do |key|
52
+ attr_reader key
53
+ define_method "#{key}=" do |name|
54
+ name = name.to_s.downcase.to_sym
55
+ if COLORS.include?(name)
56
+ instance_variable_set ivar_name(key), name
57
+ else
58
+ raise ArgumentError, "unknown color '#{name}'"
59
+ end
60
+ end
61
+ end
62
+ end
63
+ ##
64
+ # Define instance methods to read and write enumeration attributes.
65
+ # * The first argument designates the attribute name.
66
+ # * The second argument designates the default value.
67
+ # * All subsequent attributes are possible values.
68
+ # * If the last attribute is a Hash, each value in the Hash designates
69
+ # aliases for the corresponding key.
70
+ def enum key, *values
71
+ aliases = {}
72
+ if values.last.is_a? Hash
73
+ values.pop.each do |value, synonyms|
74
+ if synonyms.is_a? Array
75
+ synonyms.each do |synonym| aliases.store synonym, value end
76
+ else
77
+ aliases.store synonyms, value
78
+ end
79
+ end
80
+ end
81
+ values.each do |value|
82
+ aliases.store value, value
83
+ end
84
+ define_method key do
85
+ name = ivar_name key
86
+ value = instance_variable_get(name) if instance_variables.include? name
87
+ value || values.first
88
+ end
89
+ define_method "#{key}=" do |arg|
90
+ if arg
91
+ arg = aliases.fetch arg do
92
+ aliases.fetch arg.to_s.downcase.gsub(/[ \-]/, '_').to_sym, arg
93
+ end
94
+ if values.any? do |val| val === arg end
95
+ instance_variable_set(ivar_name(key), arg)
96
+ else
97
+ valid = values.collect do |val| val.inspect end.join ', '
98
+ raise ArgumentError,
99
+ "Invalid value '#{arg.inspect}' for #{key}. Valid values are: #{valid}"
100
+ end
101
+ else
102
+ instance_variable_set ivar_name(key), values.first
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,46 @@
1
+ module Spreadsheet
2
+ ##
3
+ # Methods for Encoding-conversions. You should not need to use any of these.
4
+ module Encodings
5
+ if RUBY_VERSION >= '1.9'
6
+ def client string, internal='UTF-16LE'
7
+ string.force_encoding internal
8
+ string.encode Spreadsheet.client_encoding
9
+ end
10
+ def internal string, client=Spreadsheet.client_encoding
11
+ string.force_encoding client
12
+ string.encode('UTF-16LE').force_encoding('ASCII-8BIT')
13
+ end
14
+ def utf8 string, client=Spreadsheet.client_encoding
15
+ string.force_encoding client
16
+ string.encode('UTF-8')
17
+ end
18
+ else
19
+ require 'iconv'
20
+ @@iconvs = {}
21
+ def client string, internal='UTF-16LE'
22
+ key = [Spreadsheet.client_encoding, internal]
23
+ iconv = @@iconvs[key] ||= Iconv.new(Spreadsheet.client_encoding, internal)
24
+ iconv.iconv string
25
+ end
26
+ def internal string, client=Spreadsheet.client_encoding
27
+ key = ['UTF-16LE', client]
28
+ iconv = @@iconvs[key] ||= Iconv.new('UTF-16LE', client)
29
+ iconv.iconv string
30
+ end
31
+ def utf8 string, client=Spreadsheet.client_encoding
32
+ key = ['UTF-8', client]
33
+ iconv = @@iconvs[key] ||= Iconv.new('UTF-8', client)
34
+ iconv.iconv string
35
+ end
36
+ end
37
+ rescue LoadError
38
+ warn "You don't have Iconv support compiled in your Ruby. Spreadsheet may not work as expected"
39
+ def client string, internal='UTF-16LE'
40
+ string.delete "\0"
41
+ end
42
+ def internal string, internal='UTF-16LE'
43
+ string.split('').zip(Array.new(string.size, 0.chr)).join
44
+ end
45
+ end
46
+ 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,386 @@
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
+ 0x0013 => :olive,
69
+ 0x0015 => :teal,
70
+ 0x0018 => :violet,
71
+ 0x0019 => :burgundy,
72
+ 0x001A => :cream,
73
+ 0x001B => :light_cyan,
74
+ 0x001C => :dark_purple,
75
+ 0x001E => :dark_blue,
76
+ 0x001F => :lavender,
77
+ 0x000a => :red,
78
+ 0x000b => :lime,
79
+ 0x000c => :blue,
80
+ 0x000d => :yellow,
81
+ 0x000e => :magenta,
82
+ 0x000f => :cyan,
83
+ 0x0010 => :brown,
84
+ 0x0011 => :green,
85
+ 0x0012 => :navy,
86
+ 0x0013 => :olive,
87
+ 0x0016 => :silver,
88
+ 0x0017 => :gray,
89
+ 0x001d => :orange,
90
+ 0x0024 => :purple,
91
+ 0x0029 => :sky_blue,
92
+ 0x002A => :sea_green,
93
+ 0x002b => :canary_yellow,
94
+ 0x002c => :cornflower,
95
+ 0x002D => :pink,
96
+ 0x002E => :fuchsia,
97
+ 0x002F => :peach,
98
+ 0x0030 => :medium_blue,
99
+ 0x0031 => :turquoise,
100
+ 0x0032 => :yellow_green,
101
+ 0x0033 => :yellow_orange,
102
+ 0x0034 => :burnt_orange,
103
+ 0x0035 => :red_orange,
104
+ 0x0036 => :dark_violet,
105
+ 0x0037 => :dark_gray,
106
+ 0x0038 => :midnight_blue,
107
+ 0x0040 => :border,
108
+ 0x0041 => :pattern_bg,
109
+ 0x0043 => :dialog_bg,
110
+ 0x004d => :chart_text,
111
+ 0x004e => :chart_bg,
112
+ 0x004f => :chart_border,
113
+ 0x0050 => :tooltip_bg,
114
+ 0x0051 => :tooltip_text,
115
+ 0x7fff => :text
116
+ }
117
+ SEDOC_ROLOC = COLOR_CODES.invert.update( :aqua => 0x000f,
118
+ :grey => 0x0017 )
119
+ BINARY_FORMATS = {
120
+ :blank => 'v3',
121
+ :boolerr => 'v3C2',
122
+ :colinfo => 'v5x2',
123
+ :font => 'v5C3x',
124
+ :labelsst => 'v3V',
125
+ :number => "v3#{EIGHT_BYTE_DOUBLE}",
126
+ :pagesetup => "v8#{EIGHT_BYTE_DOUBLE}2v",
127
+ :rk => 'v3V',
128
+ :row => 'v4x4V',
129
+ :window2 => 'v4x2v2x4',
130
+ :xf => 'v3C4V2v',
131
+ }
132
+ # From BIFF5 on, the built-in number formats will be omitted. The built-in
133
+ # formats are dependent on the current regional settings of the operating
134
+ # system. The following table shows which number formats are used by
135
+ # default in a US-English environment. All indexes from 0 to 163 are
136
+ # reserved for built-in formats.
137
+ BUILTIN_FORMATS = { # TODO: locale support
138
+ 0 => 'GENERAL',
139
+ 1 => '0',
140
+ 2 => '0.00',
141
+ 3 => '#,##0',
142
+ 4 => '#,##0.00',
143
+ 5 => '"$"#,##0_);("$"#,##0)',
144
+ 6 => '"$"#,##0_);[Red]("$"#,##0)',
145
+ 7 => '"$"#,##0.00_);("$"#,##0.00)',
146
+ 8 => '"$"#,##0.00_);[Red]("$"#,##0.00)',
147
+ 9 => '0%',
148
+ 10 => '0.00%',
149
+ 11 => '0.00E+00',
150
+ 12 => '# ?/?',
151
+ 13 => '# ??/??',
152
+ 14 => 'M/D/YY',
153
+ 15 => 'D-MMM-YY',
154
+ 16 => 'D-MMM',
155
+ 17 => 'MMM-YY',
156
+ 18 => 'h:mm AM/PM',
157
+ 19 => 'h:mm:ss AM/PM',
158
+ 20 => 'h:mm',
159
+ 21 => 'h:mm:ss',
160
+ 22 => 'M/D/YY h:mm',
161
+ 37 => '_(#,##0_);(#,##0)',
162
+ 38 => '_(#,##0_);[Red](#,##0)',
163
+ 39 => '_(#,##0.00_);(#,##0.00)',
164
+ 40 => '_(#,##0.00_);[Red](#,##0.00)',
165
+ 41 => '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)',
166
+ 42 => '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
167
+ 43 => '_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
168
+ 44 => '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
169
+ 45 => 'mm:ss',
170
+ 46 => '[h]:mm:ss',
171
+ 47 => 'mm:ss.0',
172
+ 48 => '##0.0E+0',
173
+ 49 => '@',
174
+ }
175
+ BUILTIN_STYLES = {
176
+ 0x00 => 'Normal',
177
+ 0x01 => 'RowLevel_lv',
178
+ 0x02 => 'ColLevel_lv',
179
+ 0x03 => 'Comma',
180
+ 0x04 => 'Currency',
181
+ 0x05 => 'Percent',
182
+ 0x06 => 'Comma',
183
+ 0x07 => 'Currency',
184
+ 0x08 => 'Hyperlink',
185
+ 0x09 => 'Followed Hyperlink',
186
+ }
187
+ ESCAPEMENT_TYPES = {
188
+ 0x0001 => :superscript,
189
+ 0x0002 => :subscript,
190
+ }
191
+ SEPYT_TNEMEPACSE = ESCAPEMENT_TYPES.invert
192
+ FONT_ENCODINGS = {
193
+ 0x00 => :iso_latin1,
194
+ 0x01 => :default,
195
+ 0x02 => :symbol,
196
+ 0x4d => :apple_roman,
197
+ 0x80 => :shift_jis,
198
+ 0x81 => :korean_hangul,
199
+ 0x82 => :korean_johab,
200
+ 0x86 => :chinese_simplified,
201
+ 0x88 => :chinese_traditional,
202
+ 0xa1 => :greek,
203
+ 0xa2 => :turkish,
204
+ 0xa3 => :vietnamese,
205
+ 0xb1 => :hebrew,
206
+ 0xb2 => :arabic,
207
+ 0xba => :baltic,
208
+ 0xcc => :cyrillic,
209
+ 0xde => :thai,
210
+ 0xee => :iso_latin2,
211
+ 0xff => :oem_latin1,
212
+ }
213
+ SGNIDOCNE_TNOF = FONT_ENCODINGS.invert
214
+ FONT_FAMILIES = {
215
+ 0x01 => :roman,
216
+ 0x02 => :swiss,
217
+ 0x03 => :modern,
218
+ 0x04 => :script,
219
+ 0x05 => :decorative,
220
+ }
221
+ SEILIMAF_TNOF = FONT_FAMILIES.invert
222
+ FONT_WEIGHTS = {
223
+ :bold => 700,
224
+ :normal => 400,
225
+ }
226
+ LEAP_ERROR = Date.new 1900, 2, 28
227
+ OPCODES = {
228
+ :blank => 0x0201, # BLANK ➜ 6.7
229
+ :boolerr => 0x0205, # BOOLERR ➜ 6.10
230
+ :boundsheet => 0x0085, # ●● BOUNDSHEET ➜ 6.12
231
+ :codepage => 0x0042, # ○ CODEPAGE ➜ 6.17
232
+ :colinfo => 0x007d, # ○○ COLINFO ➜ 6.18
233
+ :continue => 0x003c, # ○ CONTINUE ➜ 6.22
234
+ :datemode => 0x0022, # ○ DATEMODE ➜ 6.25
235
+ :dbcell => 0x0a0b, # ○ DBCELL
236
+ :dimensions => 0x0200, # ● DIMENSIONS ➜ 6.31
237
+ :eof => 0x000a, # ● EOF ➜ 6.36
238
+ :font => 0x0031, # ●● FONT ➜ 6.43
239
+ :format => 0x041e, # ○○ FORMAT (Number Format) ➜ 6.45
240
+ :formula => 0x0006, # FORMULA ➜ 6.46
241
+ :hlink => 0x01b8, # HLINK ➜ 6.52 (BIFF8 only)
242
+ :label => 0x0204, # LABEL ➜ 6.59 (BIFF2-BIFF7)
243
+ :labelsst => 0x00fd, # LABELSST ➜ 6.61 (BIFF8 only)
244
+ :mulblank => 0x00be, # MULBLANK ➜ 6.64 (BIFF5-BIFF8)
245
+ :mulrk => 0x00bd, # MULRK ➜ 6.65 (BIFF5-BIFF8)
246
+ :number => 0x0203, # NUMBER ➜ 6.68
247
+ :rk => 0x027e, # RK ➜ 6.82 (BIFF3-BIFF8)
248
+ :row => 0x0208, # ● ROW ➜ 6.83
249
+ :rstring => 0x00d6, # RSTRING ➜ 6.84 (BIFF5/BIFF7)
250
+ :sst => 0x00fc, # ● SST ➜ 6.96
251
+ :string => 0x0207, # STRING ➜ 6.98
252
+ :style => 0x0293, # ●● STYLE ➜ 6.99
253
+ :xf => 0x00e0, # ●● XF ➜ 6.115
254
+ :sharedfmla => 0x04bc, # SHAREDFMLA ➜ 5.94
255
+ ########################## Unhandled Opcodes ################################
256
+ :extsst => 0x00ff, # ● EXTSST ➜ 6.40
257
+ :index => 0x020b, # ○ INDEX ➜ 5.7 (Row Blocks), ➜ 6.55
258
+ :uncalced => 0x005e, # ○ UNCALCED ➜ 6.104
259
+ ########################## ○ Calculation Settings Block ➜ 5.3
260
+ :calccount => 0x000c, # ○ CALCCOUNT ➜ 6.14
261
+ :calcmode => 0x000d, # ○ CALCMODE ➜ 6.15
262
+ :precision => 0x000e, # ○ PRECISION ➜ 6.74 (moved to Workbook Globals
263
+ # Substream in BIFF5-BIFF8)
264
+ :refmode => 0x000f, # ○ REFMODE ➜ 6.80
265
+ :delta => 0x0010, # ○ DELTA ➜ 6.30
266
+ :iteration => 0x0011, # ○ ITERATION ➜ 6.57
267
+ :saverecalc => 0x005f, # ○ SAVERECALC ➜ 6.85 (BIFF3-BIFF8 only)
268
+ ########################## ○ Workbook Protection Block ➜ 5.18
269
+ :protect => 0x0012, # ○ PROTECT
270
+ # Worksheet contents: 1 = protected (➜ 6.77)
271
+ :windowprot => 0x0019, # ○ WINDOWPROTECT Window settings: 1 = protected
272
+ # (BIFF4W only, ➜ 6.110)
273
+ :objectprot => 0x0063, # ○ OBJECTPROTECT
274
+ # Embedded objects: 1 = protected (➜ 6.69)
275
+ :scenprotect => 0x00dd, # ○ SCENPROTECT
276
+ # Scenarios: 1 = protected (BIFF5-BIFF8, ➜ 6.86)
277
+ :password => 0x0013, # ○ PASSWORD Hash value of the password;
278
+ # 0 = no password (➜ 6.72)
279
+ ########################## ○ File Protection Block ➜ 5.19
280
+ :writeprot => 0x0086, # ○ WRITEPROT File is write protected
281
+ # (BIFF3-BIFF8, ➜ 6.112), password in FILESHARING
282
+ :filepass => 0x002f, # ○ FILEPASS File is read/write-protected,
283
+ # encryption information (➜ 6.41)
284
+ :writeaccess => 0x005c, # ○ WRITEACCESS User name (BIFF3-BIFF8, ➜ 6.111)
285
+ :filesharing => 0x005b, # ○ FILESHARING File sharing options
286
+ # (BIFF3-BIFF8, ➜ 6.42)
287
+ ########################## ○ Link Table ➜ 5.10.3
288
+ # ●● SUPBOOK Block(s)
289
+ # Settings for a referenced document
290
+ :supbook => 0x01ae, # ● SUPBOOK ➜ 6.100
291
+ :externname => 0x0223, # ○○ EXTERNNAME ➜ 6.38
292
+ :xct => 0x0059, # ○○ ● XCT ➜ 6.114
293
+ :crn => 0x005a, # ●● CRN ➜ 6.24
294
+ :externsheet => 0x0017, # ● EXTERNSHEET ➜ 6.39
295
+ :name => 0x0218, # ○○ NAME ➜ 6.66
296
+ ##########################
297
+ :window1 => 0x003d, # ● WINDOW1 ➜ 6.108 (has information on
298
+ # which Spreadsheet is 'active')
299
+ :backup => 0x0040, # ○ BACKUP ➜ 6.5
300
+ :country => 0x008c, # ○ COUNTRY (Make writeable?) ➜ 6.23
301
+ :hideobj => 0x008d, # ○ HIDEOBJ ➜ 6.52
302
+ :palette => 0x0092, # ○ PALETTE ➜ 6.70
303
+ :fngroupcnt => 0x009c, # ○ FNGROUPCOUNT
304
+ :bookbool => 0x00da, # ○ BOOKBOOL ➜ 6.9
305
+ :tabid => 0x013d, # ○ TABID
306
+ :useselfs => 0x0160, # ○ USESELFS (Natural Language Formulas) ➜ 6.105
307
+ :dsf => 0x0161, # ○ DSF (Double Stream File) ➜ 6.32
308
+ :refreshall => 0x01b7, # ○ REFRESHALL
309
+ ########################## ● Worksheet View Settings Block ➜ 5.5
310
+ :window2 => 0x023e, # ● WINDOW2 ➜ 5.110
311
+ :scl => 0x00a0, # ○ SCL ➜ 5.92 (BIFF4-BIFF8 only)
312
+ :pane => 0x0041, # ○ PANE ➜ 5.75
313
+ :selection => 0x001d, # ○○ SELECTION ➜ 5.93
314
+ ########################## ○ Page Settings Block ➜ 5.4
315
+ :hpagebreaks => 0x001b, # ○ HORIZONTALPAGEBREAKS ➜ 6.54
316
+ :vpagebreaks => 0x001a, # ○ VERTICALPAGEBREAKS ➜ 6.107
317
+ :header => 0x0014, # ○ HEADER ➜ 6.51
318
+ :footer => 0x0015, # ○ FOOTER ➜ 6.44
319
+ :hcenter => 0x0083, # ○ HCENTER ➜ 6.50 (BIFF3-BIFF8 only)
320
+ :vcenter => 0x0084, # ○ VCENTER ➜ 6.106 (BIFF3-BIFF8 only)
321
+ :leftmargin => 0x0026, # ○ LEFTMARGIN ➜ 6.62
322
+ :rightmargin => 0x0027, # ○ RIGHTMARGIN ➜ 6.81
323
+ :topmargin => 0x0028, # ○ TOPMARGIN ➜ 6.103
324
+ :bottommargin => 0x0029, # ○ BOTTOMMARGIN ➜ 6.11
325
+ # ○ PLS (opcode unknown)
326
+ :pagesetup => 0x00a1, # ○ PAGESETUP ➜ 6.89 (BIFF4-BIFF8 only)
327
+ :bitmap => 0x00e9, # ○ BITMAP ➜ 6.6 (Background-Bitmap, BIFF8 only)
328
+ ##########################
329
+ :printheaders => 0x002a, # ○ PRINTHEADERS ➜ 6.76
330
+ :printgridlns => 0x002b, # ○ PRINTGRIDLINES ➜ 6.75
331
+ :gridset => 0x0082, # ○ GRIDSET ➜ 6.48
332
+ :guts => 0x0080, # ○ GUTS ➜ 6.49
333
+ :defrowheight => 0x0225, # ○ DEFAULTROWHEIGHT ➜ 6.28
334
+ :wsbool => 0x0081, # ○ WSBOOL ➜ 6.113
335
+ :defcolwidth => 0x0055, # ○ DEFCOLWIDTH ➜ 6.29
336
+ :sort => 0x0090, # ○ SORT ➜ 6.95
337
+ }
338
+ =begin ## unknown opcodes
339
+ 0x00bf, 0x00c0, 0x00c1, 0x00e1, 0x00e2, 0x00eb, 0x01af, 0x01bc
340
+ =end
341
+ SEDOCPO = OPCODES.invert
342
+ TWIPS = 20
343
+ UNDERLINE_TYPES = {
344
+ 0x0001 => :single,
345
+ 0x0002 => :double,
346
+ 0x0021 => :single_accounting,
347
+ 0x0022 => :double_accounting,
348
+ }
349
+ SEPYT_ENILREDNU = UNDERLINE_TYPES.invert
350
+ XF_H_ALIGN = {
351
+ :default => 0,
352
+ :left => 1,
353
+ :center => 2,
354
+ :right => 3,
355
+ :fill => 4,
356
+ :justify => 5,
357
+ :merge => 6,
358
+ :distributed => 7,
359
+ }
360
+ NGILA_H_FX = XF_H_ALIGN.invert
361
+ XF_TEXT_DIRECTION = {
362
+ :context => 0,
363
+ :left_to_right => 1,
364
+ :right_to_left => 2,
365
+ }
366
+ NOITCERID_TXET_FX = XF_TEXT_DIRECTION.invert
367
+ XF_V_ALIGN = {
368
+ :top => 0,
369
+ :middle => 1,
370
+ :bottom => 2,
371
+ :justify => 3,
372
+ :distributed => 4,
373
+ }
374
+ NGILA_V_FX = XF_V_ALIGN.invert
375
+ OPCODE_SIZE = 4
376
+ ROW_HEIGHT = 12.1
377
+ SST_CHUNKSIZE = 20
378
+ def binfmt key
379
+ BINARY_FORMATS[key]
380
+ end
381
+ def opcode key
382
+ OPCODES[key]
383
+ end
384
+ end
385
+ end
386
+ end