writeexcel 0.6.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -13,6 +13,9 @@ tmtags
13
13
  ## VIM
14
14
  *.swp
15
15
 
16
+ ## REDCAR
17
+ .redcar
18
+
16
19
  ## PROJECT::GENERAL
17
20
  coverage
18
21
  rdoc
@@ -80,6 +80,8 @@ when use urf8 string data.
80
80
  * ruby 1.8, ruby 1.9.1, ruby 1.9.2
81
81
 
82
82
  == Recent Changes
83
+ v0.6.5
84
+ * Bug fix. if workbook already has worksheet of utf8 name, Workbook#add_worksheet, Workbook#add_chart, Workbook#add_chart_ext raise exception when add new worksheet of utf8 name.
83
85
 
84
86
  v0.6.4
85
87
  * Bug fix. endless loop when inserted image size > 8224bytes.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.4
1
+ 0.6.5
@@ -54,8 +54,6 @@ module Writeexcel
54
54
  class Chart < Worksheet
55
55
  require 'writeexcel/helper'
56
56
 
57
- NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]\{\}^` ~\0\n]/
58
-
59
57
  ###############################################################################
60
58
  #
61
59
  # factory()
@@ -691,17 +689,9 @@ def encode_utf16(str, encoding = 0) # :nodoc:
691
689
  ruby_19 { string = convert_to_ascii_if_ascii(string) }
692
690
 
693
691
  # Handle utf8 strings.
694
- ruby_18 do
695
- if string =~ NonAscii
696
- string = utf8_to_16be(string)
697
- encoding = 1
698
- end
699
- end
700
- ruby_19 do
701
- if string.encoding == Encoding::UTF_8
702
- string = utf8_to_16be(string)
703
- encoding = 1
704
- end
692
+ if is_utf8?(string)
693
+ string = utf8_to_16be(string)
694
+ encoding = 1
705
695
  end
706
696
 
707
697
  # Chart strings are limited to 255 characters.
@@ -23,7 +23,7 @@
23
23
  module Writeexcel
24
24
 
25
25
  class Format < Colors
26
- NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]\{\}^` ~\0\n]/
26
+ require 'writeexcel/helper'
27
27
 
28
28
  ###############################################################################
29
29
  #
@@ -373,17 +373,9 @@ def get_font # :nodoc:
373
373
  ruby_19 { rgch = convert_to_ascii_if_ascii(rgch) }
374
374
 
375
375
  # Handle utf8 strings
376
- ruby_18 do
377
- if rgch =~ NonAscii
378
- rgch = utf8_to_16be(rgch)
379
- encoding = 1
380
- end
381
- end
382
- ruby_19 do
383
- if rgch.encoding == Encoding::UTF_8
384
- rgch = utf8_to_16be(rgch)
385
- encoding = 1
386
- end
376
+ if is_utf8?(rgch)
377
+ rgch = utf8_to_16be(rgch)
378
+ encoding = 1
387
379
  end
388
380
 
389
381
  cch = rgch.bytesize
@@ -19,8 +19,6 @@ module Writeexcel
19
19
  class Formula < ExcelFormulaParser #:nodoc:
20
20
  require 'writeexcel/helper'
21
21
 
22
- NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]\{\}^` ~\0\n]/
23
-
24
22
  attr_accessor :byte_order, :workbook, :ext_sheets, :ext_refs, :ext_ref_count
25
23
 
26
24
  def initialize(byte_order)
@@ -313,19 +311,10 @@ def convert_string(str)
313
311
  ruby_19 { str.length }
314
312
 
315
313
  # Handle utf8 strings
316
- ruby_18 do
317
- if str =~ NonAscii
318
- str = utf8_to_16le(str)
319
- ruby_19 { str.force_encoding('BINARY') }
320
- encoding = 1
321
- end
322
- end
323
- ruby_19 do
324
- if str.encoding == Encoding::UTF_8
325
- str = utf8_to_16le(str)
326
- ruby_19 { str.force_encoding('BINARY') }
327
- encoding = 1
328
- end
314
+ if is_utf8?(str)
315
+ str = utf8_to_16le(str)
316
+ ruby_19 { str.force_encoding('BINARY') }
317
+ encoding = 1
329
318
  end
330
319
 
331
320
  exit "String in formula has more than 255 chars\n" if length > 255
@@ -513,15 +502,9 @@ def get_sheet_index(sheet_name)
513
502
  ruby_19 { sheet_name = convert_to_ascii_if_ascii(sheet_name) }
514
503
 
515
504
  # Handle utf8 sheetnames
516
- ruby_18 do
517
- if sheet_name =~ NonAscii
518
- sheet_name = utf8_to_16be(sheet_name)
519
- end
520
- end
521
- ruby_19 do
522
- if sheet_name.encoding == Encoding::UTF_8
523
- sheet_name = sheet_name.encode('UTF-16BE')
524
- end
505
+ if is_utf8?(sheet_name)
506
+ ruby_18 { sheet_name = utf8_to_16be(sheet_name) } ||
507
+ ruby_19 { sheet_name = sheet_name.encode('UTF-16BE') }
525
508
  end
526
509
 
527
510
  if @ext_sheets[sheet_name].nil?
@@ -66,3 +66,10 @@ def chars_to_col(chars)
66
66
  col
67
67
  end
68
68
  private :chars_to_col
69
+
70
+ NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]\{\}^` ~\0\n]/
71
+
72
+ def is_utf8?(str)
73
+ ruby_18 { str =~ NonAscii } ||
74
+ ruby_19 { str.encoding == Encoding::UTF_8 }
75
+ end
@@ -26,18 +26,23 @@ class Workbook < BIFFWriter
26
26
  require 'writeexcel/properties'
27
27
  require 'writeexcel/helper'
28
28
 
29
- NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]\{\}^` ~\0\n]/
30
-
31
- BOF = 11 # :nodoc:
29
+ BOF = 12 # :nodoc:
32
30
  EOF = 4 # :nodoc:
33
31
  SheetName = "Sheet" # :nodoc:
34
32
 
33
+ private
34
+
35
+ attr_accessor :add_doc_properties #:nodoc:
36
+ attr_reader :formats, :defined_names #:nodoc:
37
+
38
+ public
39
+
35
40
  #
36
- # file is a filename (as string) or io object where to out spreadsheet data.
37
- # you can set default format of workbook using default_formats.
41
+ # _file_ is a filename (as string) or io object where to out spreadsheet data.
42
+ # you can set default format of workbook using _default_formats_.
38
43
  #
39
44
  # A new Excel workbook is created using the new() constructor which accepts
40
- # either a filename or a filehandle as a parameter. The following example
45
+ # either a filename or an IO object as a parameter. The following example
41
46
  # creates a new Excel file based on a filename:
42
47
  #
43
48
  # workbook = WriteExcel.new('filename.xls')
@@ -74,8 +79,6 @@ def initialize(file, default_formats = {})
74
79
  @parser = Writeexcel::Formula.new(@byte_order)
75
80
  @tempdir = nil
76
81
  @date_1904 = false
77
- @sheet =
78
-
79
82
  @selected = 0
80
83
  @xf_index = 0
81
84
  @fileclosed = false
@@ -88,7 +91,6 @@ def initialize(file, default_formats = {})
88
91
  @codepage = 0x04E4
89
92
  @country = 1
90
93
  @worksheets = []
91
- @sheetnames = []
92
94
  @formats = []
93
95
  @palette = []
94
96
  @biff_only = 0
@@ -117,7 +119,6 @@ def initialize(file, default_formats = {})
117
119
  @hideobj = 0
118
120
  @compatibility = 0
119
121
 
120
- @add_doc_properties = 0
121
122
  @summary = ''
122
123
  @doc_summary = ''
123
124
  @localtime = Time.now
@@ -165,7 +166,7 @@ def initialize(file, default_formats = {})
165
166
 
166
167
  ###############################################################################
167
168
  #
168
- # _get_checksum_method.
169
+ # get_checksum_method.
169
170
  #
170
171
  # Check for modules available to calculate image checksum. Excel uses MD4 but
171
172
  # MD5 will also work.
@@ -182,12 +183,6 @@ def get_checksum_method #:nodoc:
182
183
  # Calls finalization methods and explicitly close the OLEwriter files
183
184
  # handle.
184
185
  #
185
- # In general your Excel file will be closed automatically when your program
186
- # ends or when the Workbook object goes out of scope, however the close method
187
- # can be used to explicitly close an Excel file.
188
- #
189
- # workbook.close
190
- #
191
186
  # An explicit close() is required if the file must be closed prior to performing
192
187
  # some external action on it such as copying it, reading its size or attaching
193
188
  # it to an email.
@@ -195,12 +190,6 @@ def get_checksum_method #:nodoc:
195
190
  # In general, if you create a file with a size of 0 bytes or you fail to create
196
191
  # a file you need to call close().
197
192
  #
198
- # The return value of close() is the same as that returned by perl when it
199
- # closes the file created by new(). This allows you to handle error conditions
200
- # in the usual way:
201
- #
202
- # $workbook.close() or die "Error closing file: $!";
203
- #
204
193
  def close
205
194
  return if @fileclosed # Prevent close() from being called twice.
206
195
 
@@ -245,11 +234,7 @@ def sheets(*args)
245
234
  if args.empty?
246
235
  @worksheets
247
236
  else
248
- ary = []
249
- args.each do |i|
250
- ary << @worksheets[i]
251
- end
252
- ary
237
+ args.collect{|i| @worksheets[i] }
253
238
  end
254
239
  end
255
240
 
@@ -266,7 +251,7 @@ def sheets(*args)
266
251
  # worksheet3 = workbook.add_worksheet('Data') # Data
267
252
  # worksheet4 = workbook.add_worksheet # Sheet4
268
253
  #
269
- # If sheetname is not specified the default Excel convention will be followed,
254
+ # If _sheetname_ is not specified the default Excel convention will be followed,
270
255
  # i.e. Sheet1, Sheet2, etc. The utf_16_be parameter is optional, see below.
271
256
  #
272
257
  # The worksheet name must be a valid Excel worksheet name, i.e. it cannot
@@ -308,14 +293,10 @@ def add_worksheet(sheetname = '', encoding = 0)
308
293
  ]
309
294
  worksheet = Writeexcel::Worksheet.new(*init_data)
310
295
  @worksheets[index] = worksheet # Store ref for iterator
311
- @sheetnames[index] = name # Store EXTERNSHEET names
312
296
  @parser.set_ext_sheets(name, index) # Store names in Formula.rb
313
297
  worksheet
314
298
  end
315
299
 
316
- ###############################################################################
317
- #
318
- # add_chart(params)
319
300
  #
320
301
  # Create a chart for embedding or as as new sheet.
321
302
  #
@@ -327,72 +308,78 @@ def add_worksheet(sheetname = '', encoding = 0)
327
308
  #
328
309
  # The properties that can be set are:
329
310
  #
330
- # :type (required)
331
- # :name (optional)
332
- # :embedded (optional)
311
+ # :type (required)
312
+ # :name (optional)
313
+ # :encoding (optional)
314
+ # :embedded (optional)
315
+ #
316
+ # * type
333
317
  #
334
- # * type
318
+ # This is a required parameter. It defines the type of chart that will be created.
335
319
  #
336
- # This is a required parameter. It defines the type of chart that will be created.
320
+ # chart = workbook.add_chart(:type => 'Chart::Line')
337
321
  #
338
- # chart = workbook.add_chart(:type => 'Chart::Line')
322
+ # The available types are:
339
323
  #
340
- # The available types are:
324
+ # 'Chart::Column'
325
+ # 'Chart::Bar'
326
+ # 'Chart::Line'
327
+ # 'Chart::Area'
328
+ # 'Chart::Pie'
329
+ # 'Chart::Scatter'
330
+ # 'Chart::Stock'
341
331
  #
342
- # 'Chart::Column'
343
- # 'Chart::Bar'
344
- # 'Chart::Line'
345
- # 'Chart::Area'
346
- # 'Chart::Pie'
347
- # 'Chart::Scatter'
348
- # 'Chart::Stock'
332
+ # * :name
349
333
  #
350
- # * :name
334
+ # Set the name for the chart sheet. The name property is optional and
335
+ # if it isn't supplied will default to Chart1 .. n. The name must be
336
+ # a valid Excel worksheet name. See add_worksheet() for more details
337
+ # on valid sheet names. The name property can be omitted for embedded
338
+ # charts.
351
339
  #
352
- # Set the name for the chart sheet. The name property is optional and
353
- # if it isn't supplied will default to Chart1 .. n. The name must be
354
- # a valid Excel worksheet name. See add_worksheet() for more details
355
- # on valid sheet names. The name property can be omitted for embedded
356
- # charts.
340
+ # chart = workbook.add_chart(
341
+ # :type => 'Chart::Line',
342
+ # :name => 'Results Chart'
343
+ # )
357
344
  #
358
- # chart = workbook.add_chart(
359
- # :type => 'Chart::Line',
360
- # :name => 'Results Chart'
361
- # )
345
+ # * :encoding
362
346
  #
363
- # * :embedded
347
+ # if :name is UTF-16BE format, pass 1 as :encoding.
364
348
  #
365
- # Specifies that the Chart object will be inserted in a worksheet via
366
- # the insert_chart() Worksheet method. It is an error to try insert a
367
- # Chart that doesn't have this flag set.
349
+ # * :embedded
368
350
  #
369
- # chart = workbook.add_chart(:type => 'Chart::Line', :embedded => 1)
351
+ # Specifies that the Chart object will be inserted in a worksheet via
352
+ # the insert_chart() Worksheet method. It is an error to try insert a
353
+ # Chart that doesn't have this flag set.
370
354
  #
371
- # # Configure the chart.
372
- # ...
355
+ # chart = workbook.add_chart(:type => 'Chart::Line', :embedded => 1)
373
356
  #
374
- # # Insert the chart into the a worksheet.
375
- # worksheet.insert_chart('E2', chart)
357
+ # # Configure the chart.
358
+ # ...
359
+ #
360
+ # # Insert the chart into the a worksheet.
361
+ # worksheet.insert_chart('E2', chart)
376
362
  #
377
363
  # See WriteExcel::Chart for details on how to configure the
378
- # chart object once it is created. See also the chart_*.pl programs in the
364
+ # chart object once it is created. See also the chart_*.rb programs in the
379
365
  # examples directory of the distro.
380
366
  #
381
- def add_chart(params)
367
+ def add_chart(properties)
382
368
  name = ''
383
369
  encoding = 0
384
370
  index = @worksheets.size
385
371
 
386
372
  # Type must be specified so we can create the required chart instance.
387
- type = params[:type]
388
- print "Must define chart type in add_chart()" if type.nil?
373
+ type = properties[:type]
374
+ raise "Must define chart type in add_chart()" if type.nil?
389
375
 
390
376
  # Ensure that the chart defaults to non embedded.
391
- embedded = params[:embedded]
377
+ embedded = properties[:embedded]
392
378
 
393
379
  # Check the worksheet name for non-embedded charts.
394
380
  unless embedded
395
- name, encoding = check_sheetname(params[:name], params[:name_encoding], 1)
381
+ name, encoding =
382
+ check_sheetname(properties[:name], properties[:encoding], true)
396
383
  end
397
384
 
398
385
  init_data = [
@@ -412,7 +399,6 @@ def add_chart(params)
412
399
  # If the chart isn't embedded let the workbook control it.
413
400
  if !embedded
414
401
  @worksheets[index] = chart # Store ref for iterator
415
- @sheetnames[index] = name # Store EXTERNSHEET names
416
402
  else
417
403
  # Set index to 0 so that the activate() and set_first_sheet() methods
418
404
  # point back to the first worksheet if used for embedded charts.
@@ -423,9 +409,6 @@ def add_chart(params)
423
409
  chart
424
410
  end
425
411
 
426
- ###############################################################################
427
- #
428
- # add_chart_ext($filename, $name)
429
412
  #
430
413
  # Add an externally created chart.
431
414
  #
@@ -454,24 +437,21 @@ def add_chart_ext(filename, name, encoding = 0)
454
437
 
455
438
  chart = Writeexcel::Chart.factory(self, type, init_data)
456
439
  @worksheets[index] = chart # Store ref for iterator
457
- @sheetnames[index] = name # Store EXTERNSHEET names
458
440
  chart
459
441
  end
460
442
 
461
443
  ###############################################################################
462
444
  #
463
- # _check_sheetname($name, $encoding)
445
+ # check_sheetname(name, encoding)
464
446
  #
465
447
  # Check for valid worksheet names. We check the length, if it contains any
466
448
  # invalid characters and if the name is unique in the workbook.
467
449
  #
468
- def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
450
+ def check_sheetname(name, encoding = 0, chart = nil) #:nodoc:
469
451
  encoding ||= 0
470
- limit = encoding != 0 ? 62 : 31
471
- invalid_char = %r![\[\]:*?/\\]!
472
452
 
473
453
  # Increment the Sheet/Chart number used for default sheet names below.
474
- if chart != 0
454
+ if chart
475
455
  @chart_count += 1
476
456
  else
477
457
  @sheet_count += 1
@@ -480,7 +460,7 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
480
460
  # Supply default Sheet/Chart name if none has been defined.
481
461
  if name.nil? || name == ""
482
462
  encoding = 0
483
- if chart != 0
463
+ if chart
484
464
  name = @chart_name + @chart_count.to_s
485
465
  else
486
466
  name = @sheet_name + @sheet_count.to_s
@@ -488,16 +468,39 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
488
468
  end
489
469
 
490
470
  ruby_19 { name = convert_to_ascii_if_ascii(name) }
471
+ check_sheetname_length(name, encoding)
472
+ check_sheetname_even(name) if encoding == 1
473
+ check_sheetname_valid_chars(name, encoding)
474
+
475
+ # Handle utf8 strings
476
+ if is_utf8?(name)
477
+ name = utf8_to_16be(name)
478
+ encoding = 1
479
+ end
491
480
 
481
+ check_sheetname_uniq(name, encoding)
482
+ [name, encoding]
483
+ end
484
+ private :check_sheetname
485
+
486
+ def check_sheetname_length(name, encoding) #:nodoc:
492
487
  # Check that sheetname is <= 31 (1 or 2 byte chars). Excel limit.
488
+ limit = encoding != 0 ? 62 : 31
493
489
  raise "Sheetname $name must be <= 31 chars" if name.bytesize > limit
490
+ end
491
+ private :check_sheetname_length
494
492
 
493
+ def check_sheetname_even(name) #:nodoc:
495
494
  # Check that Unicode sheetname has an even number of bytes
496
- if encoding == 1 && (name.bytesize % 2 != 0)
495
+ if (name.bytesize % 2 != 0)
497
496
  raise "Odd number of bytes in Unicode worksheet name: #{name}"
498
497
  end
498
+ end
499
+ private :check_sheetname_even
499
500
 
501
+ def check_sheetname_valid_chars(name, encoding) #:nodoc:
500
502
  # Check that sheetname doesn't contain any invalid characters
503
+ invalid_char = %r![\[\]:*?/\\]!
501
504
  if encoding != 1 && name =~ invalid_char
502
505
  # Check ASCII names
503
506
  raise "Invalid character []:*?/\\ in worksheet name: #{name}"
@@ -512,32 +515,21 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
512
515
  str = $~.post_match
513
516
  end
514
517
  end
518
+ end
519
+ private :check_sheetname_valid_chars
515
520
 
516
- # Handle utf8 strings
517
- ruby_18 do
518
- if name =~ NonAscii
519
- name = utf8_to_16be(name)
520
- encoding = 1
521
- end
522
- end
523
- ruby_19 do
524
- if name.encoding == Encoding::UTF_8
525
- name = utf8_to_16be(name)
526
- encoding = 1
527
- end
528
- end
529
-
530
- # Check that the worksheet name doesn't already exist since this is a fatal
531
- # error in Excel 97. The check must also exclude case insensitive matches
532
- # since the names 'Sheet1' and 'sheet1' are equivalent. The tests also have
533
- # to take the encoding into account.
534
- #
521
+ # Check that the worksheet name doesn't already exist since this is a fatal
522
+ # error in Excel 97. The check must also exclude case insensitive matches
523
+ # since the names 'Sheet1' and 'sheet1' are equivalent. The tests also have
524
+ # to take the encoding into account.
525
+ #
526
+ def check_sheetname_uniq(name, encoding) #:nodoc:
535
527
  @worksheets.each do |worksheet|
536
528
  name_a = name
537
529
  encd_a = encoding
538
530
  name_b = worksheet.name
539
531
  encd_b = worksheet.encoding
540
- error = 0;
532
+ error = false
541
533
 
542
534
  if encd_a == 0 and encd_b == 0
543
535
  error = (name_a.downcase == name_b.downcase)
@@ -569,9 +561,8 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
569
561
  raise "Worksheet name '#{name}', with case ignored, is already in use"
570
562
  end
571
563
  end
572
- [name, encoding]
573
564
  end
574
- private :check_sheetname
565
+ private :check_sheetname_uniq
575
566
 
576
567
  #
577
568
  # The add_format method can be used to create new Format objects which are
@@ -584,11 +575,11 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
584
575
  # See the "CELL FORMATTING" section for more details about Format properties and how to set them.
585
576
  #
586
577
  def add_format(*args)
587
- formats = {}
588
- args.each { |arg| formats = formats.merge(arg) }
589
- format = Writeexcel::Format.new(@xf_index, @default_formats.merge(formats))
578
+ fmts = {}
579
+ args.each { |arg| fmts = fmts.merge(arg) }
580
+ format = Writeexcel::Format.new(@xf_index, @default_formats.merge(fmts))
590
581
  @xf_index += 1
591
- @formats.push format # Store format reference
582
+ formats.push format # Store format reference
592
583
  format
593
584
  end
594
585
 
@@ -819,7 +810,6 @@ def set_palette_xl97 #:nodoc:
819
810
  [0x33, 0x33, 0x99, 0x00], # 62
820
811
  [0x33, 0x33, 0x33, 0x00] # 63
821
812
  ]
822
- 0
823
813
  end
824
814
  private :set_palette_xl97
825
815
 
@@ -948,7 +938,7 @@ def define_name(name, formula, encoding = 0)
948
938
  # Parse the tokens into a formula string.
949
939
  formula = parser.parse_tokens(tokens)
950
940
 
951
- @defined_names.push(
941
+ defined_names.push(
952
942
  {
953
943
  :name => name,
954
944
  :encoding => encoding,
@@ -957,7 +947,7 @@ def define_name(name, formula, encoding = 0)
957
947
  }
958
948
  )
959
949
 
960
- index = @defined_names.size
950
+ index = defined_names.size
961
951
 
962
952
  parser.set_ext_name(name, index)
963
953
  end
@@ -1020,107 +1010,111 @@ def set_properties(params)
1020
1010
  params.each do |k, v|
1021
1011
  params[k] = convert_to_ascii_if_ascii(v) if v.respond_to?(:to_str)
1022
1012
  end
1023
- # List of valid input parameters.
1024
- properties = {
1025
- :codepage => [0x0001, 'VT_I2' ],
1026
- :title => [0x0002, 'VT_LPSTR' ],
1027
- :subject => [0x0003, 'VT_LPSTR' ],
1028
- :author => [0x0004, 'VT_LPSTR' ],
1029
- :keywords => [0x0005, 'VT_LPSTR' ],
1030
- :comments => [0x0006, 'VT_LPSTR' ],
1031
- :last_author => [0x0008, 'VT_LPSTR' ],
1032
- :created => [0x000C, 'VT_FILETIME'],
1033
- :category => [0x0002, 'VT_LPSTR' ],
1034
- :manager => [0x000E, 'VT_LPSTR' ],
1035
- :company => [0x000F, 'VT_LPSTR' ],
1036
- :utf8 => 1
1037
- }
1038
1013
 
1039
1014
  # Check for valid input parameters.
1040
- params.each_key do |k|
1041
- unless properties.has_key?(k)
1042
- raise "Unknown parameter '#{k}' in set_properties()";
1043
- end
1044
- end
1015
+ check_valid_params_for_properties(params)
1045
1016
 
1046
1017
  # Set the creation time unless specified by the user.
1047
- unless params.has_key?(:created)
1048
- params[:created] = @localtime
1049
- end
1018
+ params[:created] = @localtime unless params.has_key?(:created)
1050
1019
 
1051
1020
  #
1052
1021
  # Create the SummaryInformation property set.
1053
1022
  #
1054
1023
 
1055
1024
  # Get the codepage of the strings in the property set.
1056
- strings = ["title", "subject", "author", "keywords", "comments", "last_author"]
1057
- params[:codepage] = get_property_set_codepage(params, strings)
1025
+ properties = [:title, :subject, :author, :keywords, :comments, :last_author]
1026
+ params[:codepage] = get_property_set_codepage(params, properties)
1058
1027
 
1059
1028
  # Create an array of property set values.
1060
- property_sets = []
1061
- strings.unshift("codepage")
1062
- strings.push("created")
1063
- strings.each do |string|
1064
- property = string.to_sym
1065
- property_sets.push(property_set(properties, property, params)) if params[property]
1066
- end
1029
+ properties.unshift(:codepage)
1030
+ properties.push(:created)
1067
1031
 
1068
1032
  # Pack the property sets.
1069
- @summary = create_summary_property_set(property_sets)
1033
+ @summary =
1034
+ create_summary_property_set(property_sets(properties, params))
1070
1035
 
1071
1036
  #
1072
1037
  # Create the DocSummaryInformation property set.
1073
1038
  #
1074
1039
 
1075
1040
  # Get the codepage of the strings in the property set.
1076
- strings = ["category", "manager", "company"]
1077
- params[:codepage] = get_property_set_codepage(params, strings)
1041
+ properties = [:category, :manager, :company]
1042
+ params[:codepage] = get_property_set_codepage(params, properties)
1078
1043
 
1079
1044
  # Create an array of property set values.
1080
- property_sets = []
1081
-
1082
- [:codepage, :category, :manager, :company].each do |property|
1083
- property_sets.push(property_set(properties, property, params)) if params[property]
1084
- end
1045
+ properties.unshift(:codepage)
1085
1046
 
1086
1047
  # Pack the property sets.
1087
- @doc_summary = create_doc_summary_property_set(property_sets)
1048
+ @doc_summary =
1049
+ create_doc_summary_property_set(property_sets(properties, params))
1088
1050
 
1089
1051
  # Set a flag for when the files is written.
1090
- @add_doc_properties = 1
1052
+ add_doc_properties = true
1091
1053
  end
1092
1054
 
1093
- def property_set(properties, property, params)
1094
- [ properties[property][0], properties[property][1], params[property] ]
1055
+ def property_set(property, params) #:nodoc:
1056
+ valid_properties[property][0..1] + [params[property]]
1095
1057
  end
1096
1058
  private :property_set
1097
1059
 
1060
+ def property_sets(properties, params) #:nodoc:
1061
+ properties.select { |property| params[property.to_sym] }.
1062
+ collect do |property|
1063
+ property_set(property.to_sym, params)
1064
+ end
1065
+ end
1066
+ private :property_sets
1067
+
1068
+ # List of valid input parameters.
1069
+ def valid_properties #:nodoc:
1070
+ {
1071
+ :codepage => [0x0001, 'VT_I2' ],
1072
+ :title => [0x0002, 'VT_LPSTR' ],
1073
+ :subject => [0x0003, 'VT_LPSTR' ],
1074
+ :author => [0x0004, 'VT_LPSTR' ],
1075
+ :keywords => [0x0005, 'VT_LPSTR' ],
1076
+ :comments => [0x0006, 'VT_LPSTR' ],
1077
+ :last_author => [0x0008, 'VT_LPSTR' ],
1078
+ :created => [0x000C, 'VT_FILETIME'],
1079
+ :category => [0x0002, 'VT_LPSTR' ],
1080
+ :manager => [0x000E, 'VT_LPSTR' ],
1081
+ :company => [0x000F, 'VT_LPSTR' ],
1082
+ :utf8 => 1
1083
+ }
1084
+ end
1085
+ private :valid_properties
1086
+
1087
+ def check_valid_params_for_properties(params) #:nodoc:
1088
+ params.each_key do |k|
1089
+ unless valid_properties.has_key?(k)
1090
+ raise "Unknown parameter '#{k}' in set_properties()";
1091
+ end
1092
+ end
1093
+ end
1094
+ private :check_valid_params_for_properties
1095
+
1098
1096
  ###############################################################################
1099
1097
  #
1100
- # _get_property_set_codepage()
1098
+ # get_property_set_codepage()
1101
1099
  #
1102
1100
  # Get the character codepage used by the strings in a property set. If one of
1103
1101
  # the strings used is utf8 then the codepage is marked as utf8. Otherwise
1104
1102
  # Latin 1 is used (although in our case this is limited to 7bit ASCII).
1105
1103
  #
1106
- def get_property_set_codepage(params, strings) #:nodoc:
1104
+ def get_property_set_codepage(params, properties) #:nodoc:
1107
1105
  # Allow for manually marked utf8 strings.
1108
- unless params[:utf8].nil?
1109
- return 0xFDE9
1110
- else
1111
- strings.each do |string|
1112
- next unless params.has_key?(string.to_sym)
1113
- ruby_18 { return 0xFDE9 if params[string.to_sym] =~ NonAscii }
1114
- ruby_19 { return 0xFDE9 if params[string.to_sym].encoding == Encoding::UTF_8 }
1115
- end
1116
- return 0x04E4; # Default codepage, Latin 1.
1106
+ return 0xFDE9 unless params[:utf8].nil?
1107
+ properties.each do |property|
1108
+ next unless params.has_key?(property.to_sym)
1109
+ return 0xFDE9 if is_utf8?(params[property.to_sym])
1117
1110
  end
1111
+ return 0x04E4; # Default codepage, Latin 1.
1118
1112
  end
1119
1113
  private :get_property_set_codepage
1120
1114
 
1121
1115
  ###############################################################################
1122
1116
  #
1123
- # _store_workbook()
1117
+ # store_workbook()
1124
1118
  #
1125
1119
  # Assemble worksheets into a workbook and send the BIFF data to an OLE
1126
1120
  # storage.
@@ -1168,7 +1162,7 @@ def store_workbook #:nodoc:
1168
1162
  end
1169
1163
 
1170
1164
  # NOTE: If any records are added between here and EOF the
1171
- # _calc_sheet_offsets() should be updated to include the new length.
1165
+ # calc_sheet_offsets() should be updated to include the new length.
1172
1166
  store_country
1173
1167
  if @ext_refs.keys.size != 0
1174
1168
  store_supbook
@@ -1213,7 +1207,7 @@ def localtime=(val) # :nodoc:
1213
1207
 
1214
1208
  ###############################################################################
1215
1209
  #
1216
- # _store_ole_filie()
1210
+ # store_ole_filie()
1217
1211
  #
1218
1212
  # Store the workbook in an OLE container using the default handler or using
1219
1213
  # OLE::Storage_Lite if the workbook data is > ~ 7MB.
@@ -1222,7 +1216,7 @@ def store_ole_filie #:nodoc:
1222
1216
  maxsize = 7_087_104
1223
1217
  # maxsize = 1
1224
1218
 
1225
- if @add_doc_properties == 0 && @biffsize <= maxsize
1219
+ if !add_doc_properties && @biffsize <= maxsize
1226
1220
  # Write the OLE file using OLEwriter if data <= 7MB
1227
1221
  ole = OLEWriter.new(@fh_out)
1228
1222
 
@@ -1266,7 +1260,7 @@ def store_ole_filie #:nodoc:
1266
1260
  streams << workbook
1267
1261
 
1268
1262
  # Create the properties streams, if any.
1269
- if @add_doc_properties != 0
1263
+ if add_doc_properties
1270
1264
  stream = "\5SummaryInformation".unpack('C*').pack('v*')
1271
1265
  summary = OLEStorageLitePPSFile.new(stream, @summary)
1272
1266
  streams << summary
@@ -1293,14 +1287,11 @@ def store_ole_filie #:nodoc:
1293
1287
 
1294
1288
  ###############################################################################
1295
1289
  #
1296
- # _calc_sheet_offsets()
1290
+ # calc_sheet_offsets()
1297
1291
  #
1298
1292
  # Calculate Worksheet BOF offsets records for use in the BOUNDSHEET records.
1299
1293
  #
1300
1294
  def calc_sheet_offsets #:nodoc:
1301
- _bof = 12
1302
- _eof = 4
1303
-
1304
1295
  offset = @datasize
1305
1296
 
1306
1297
  # Add the length of the COUNTRY record
@@ -1316,16 +1307,16 @@ def calc_sheet_offsets #:nodoc:
1316
1307
  offset += calculate_extern_sizes
1317
1308
 
1318
1309
  # Add the length of the MSODRAWINGGROUP records including an extra 4 bytes
1319
- # for any CONTINUE headers. See _add_mso_drawing_group_continue().
1310
+ # for any CONTINUE headers. See add_mso_drawing_group_continue().
1320
1311
  mso_size = @mso_size
1321
1312
  mso_size += 4 * Integer((mso_size -1) / Float(@limit))
1322
1313
  offset += mso_size
1323
1314
 
1324
1315
  @worksheets.each do |sheet|
1325
- offset += _bof + sheet.name.bytesize
1316
+ offset += BOF + sheet.name.bytesize
1326
1317
  end
1327
1318
 
1328
- offset += _eof
1319
+ offset += EOF
1329
1320
  @worksheets.each do |sheet|
1330
1321
  sheet.offset = offset
1331
1322
  sheet.close
@@ -1338,7 +1329,7 @@ def calc_sheet_offsets #:nodoc:
1338
1329
 
1339
1330
  ###############################################################################
1340
1331
  #
1341
- # _calc_mso_sizes()
1332
+ # calc_mso_sizes()
1342
1333
  #
1343
1334
  # Calculate the MSODRAWINGGROUP sizes and the indexes of the Worksheet
1344
1335
  # MSODRAWING records.
@@ -1419,7 +1410,7 @@ def calc_mso_sizes #:nodoc:
1419
1410
 
1420
1411
  ###############################################################################
1421
1412
  #
1422
- # _process_images()
1413
+ # process_images()
1423
1414
  #
1424
1415
  # We need to process each image in each worksheet and extract information.
1425
1416
  # Some of this information is stored and used in the Workbook and some is
@@ -1554,10 +1545,10 @@ def process_images #:nodoc:
1554
1545
 
1555
1546
  ###############################################################################
1556
1547
  #
1557
- # _image_checksum()
1548
+ # image_checksum()
1558
1549
  #
1559
1550
  # Generate a checksum for the image using whichever module is available..The
1560
- # available modules are checked in _get_checksum_method(). Excel uses an MD4
1551
+ # available modules are checked in get_checksum_method(). Excel uses an MD4
1561
1552
  # checksum but any other will do. In the event of no checksum module being
1562
1553
  # available we simulate a checksum using the image index.
1563
1554
  #
@@ -1580,7 +1571,7 @@ def image_checksum(data, index1, index2 = 0) #:nodoc:
1580
1571
 
1581
1572
  ###############################################################################
1582
1573
  #
1583
- # _process_png()
1574
+ # process_png()
1584
1575
  #
1585
1576
  # Extract width and height information from a PNG file.
1586
1577
  #
@@ -1595,7 +1586,7 @@ def process_png(data) #:nodoc:
1595
1586
 
1596
1587
  ###############################################################################
1597
1588
  #
1598
- # _process_bmp()
1589
+ # process_bmp()
1599
1590
  #
1600
1591
  # Extract width and height information from a BMP file.
1601
1592
  #
@@ -1644,7 +1635,7 @@ def process_bmp(data, filename) #:nodoc:
1644
1635
 
1645
1636
  ###############################################################################
1646
1637
  #
1647
- # _process_jpg()
1638
+ # process_jpg()
1648
1639
  #
1649
1640
  # Extract width and height information from a JPEG file.
1650
1641
  #
@@ -1683,12 +1674,12 @@ def process_jpg(data, filename) # :nodoc:
1683
1674
 
1684
1675
  ###############################################################################
1685
1676
  #
1686
- # _store_all_fonts()
1677
+ # store_all_fonts()
1687
1678
  #
1688
1679
  # Store the Excel FONT records.
1689
1680
  #
1690
1681
  def store_all_fonts #:nodoc:
1691
- format = @formats[15] # The default cell format.
1682
+ format = formats[15] # The default cell format.
1692
1683
  font = format.get_font
1693
1684
 
1694
1685
  # Fonts are 0-indexed. According to the SDK there is no index 4,
@@ -1751,7 +1742,7 @@ def store_all_fonts #:nodoc:
1751
1742
  # Fonts that are marked as '_font_only' are always stored. These are used
1752
1743
  # mainly for charts and may not have an associated XF record.
1753
1744
 
1754
- @formats.each do |fmt|
1745
+ formats.each do |fmt|
1755
1746
  key = fmt.get_font_key
1756
1747
  if fmt.font_only == 0 and !fonts[key].nil?
1757
1748
  # FONT has already been used
@@ -1774,7 +1765,7 @@ def store_all_fonts #:nodoc:
1774
1765
 
1775
1766
  ###############################################################################
1776
1767
  #
1777
- # _store_all_num_formats()
1768
+ # store_all_num_formats()
1778
1769
  #
1779
1770
  # Store user defined numerical formats i.e. FORMAT records
1780
1771
  #
@@ -1785,7 +1776,7 @@ def store_all_num_formats #:nodoc:
1785
1776
  # Iterate through the XF objects and write a FORMAT record if it isn't a
1786
1777
  # built-in format type and if the FORMAT string hasn't already been used.
1787
1778
  #
1788
- @formats.each do |format|
1779
+ formats.each do |format|
1789
1780
  num_format = format.num_format
1790
1781
  encoding = format.num_format_enc
1791
1782
 
@@ -1813,12 +1804,12 @@ def store_all_num_formats #:nodoc:
1813
1804
 
1814
1805
  ###############################################################################
1815
1806
  #
1816
- # _store_all_xfs()
1807
+ # store_all_xfs()
1817
1808
  #
1818
1809
  # Write all XF records.
1819
1810
  #
1820
1811
  def store_all_xfs #:nodoc:
1821
- @formats.each do |format|
1812
+ formats.each do |format|
1822
1813
  xf = format.get_xf
1823
1814
  append(xf)
1824
1815
  end
@@ -1827,7 +1818,7 @@ def store_all_xfs #:nodoc:
1827
1818
 
1828
1819
  ###############################################################################
1829
1820
  #
1830
- # _store_all_styles()
1821
+ # store_all_styles()
1831
1822
  #
1832
1823
  # Write all STYLE records.
1833
1824
  #
@@ -1858,13 +1849,13 @@ def store_all_styles #:nodoc:
1858
1849
 
1859
1850
  ###############################################################################
1860
1851
  #
1861
- # _store_names()
1852
+ # store_names()
1862
1853
  #
1863
1854
  # Write the NAME record to define the print area and the repeat rows and cols.
1864
1855
  #
1865
1856
  def store_names # :nodoc:
1866
1857
  # Create the user defined names.
1867
- @defined_names.each do |defined_name|
1858
+ defined_names.each do |defined_name|
1868
1859
  store_name(
1869
1860
  defined_name[:name],
1870
1861
  defined_name[:encoding],
@@ -1875,20 +1866,28 @@ def store_names # :nodoc:
1875
1866
 
1876
1867
  # Sort the worksheets into alphabetical order by name. This is a
1877
1868
  # requirement for some non-English language Excel patch levels.
1878
- worksheets = @worksheets.sort_by{ |x| x.name }
1869
+ sorted_worksheets = @worksheets.sort_by{ |x| x.name }
1879
1870
 
1880
1871
  # Create the autofilter NAME records
1881
- worksheets.each do |worksheet|
1872
+ create_autofilter_name_records(sorted_worksheets)
1873
+
1874
+ # Create the print area NAME records
1875
+ create_print_area_name_records(sorted_worksheets)
1876
+
1877
+ # Create the print title NAME records
1878
+ create_print_title_name_records(sorted_worksheets)
1879
+ end
1880
+
1881
+ def create_autofilter_name_records(sorted_worksheets) #:nodoc:
1882
+ sorted_worksheets.each do |worksheet|
1882
1883
  index = worksheet.index
1883
- key = "#{index}:#{index}"
1884
- ref = @ext_refs[key]
1885
1884
 
1886
1885
  # Write a Name record if Autofilter has been defined
1887
1886
  if worksheet.filter_count != 0
1888
1887
  store_name_short(
1889
1888
  worksheet.index,
1890
1889
  0x0D, # NAME type = Filter Database
1891
- ref,
1890
+ @ext_refs["#{index}:#{index}"],
1892
1891
  worksheet.filter_area[0],
1893
1892
  worksheet.filter_area[1],
1894
1893
  worksheet.filter_area[2],
@@ -1897,19 +1896,19 @@ def store_names # :nodoc:
1897
1896
  )
1898
1897
  end
1899
1898
  end
1899
+ end
1900
+ private :create_autofilter_name_records
1900
1901
 
1901
- # Create the print area NAME records
1902
- worksheets.each do |worksheet|
1902
+ def create_print_area_name_records(sorted_worksheets) #:nodoc:
1903
+ sorted_worksheets.each do |worksheet|
1903
1904
  index = worksheet.index
1904
- key = "#{index}:#{index}"
1905
- ref = @ext_refs[key]
1906
1905
 
1907
1906
  # Write a Name record if the print area has been defined
1908
1907
  if !worksheet.print_rowmin.nil?
1909
1908
  store_name_short(
1910
1909
  worksheet.index,
1911
1910
  0x06, # NAME type = Print_Area
1912
- ref,
1911
+ @ext_refs["#{index}:#{index}"],
1913
1912
  worksheet.print_rowmin,
1914
1913
  worksheet.print_rowmax,
1915
1914
  worksheet.print_colmin,
@@ -1917,9 +1916,11 @@ def store_names # :nodoc:
1917
1916
  )
1918
1917
  end
1919
1918
  end
1919
+ end
1920
+ private :create_print_area_name_records
1920
1921
 
1921
- # Create the print title NAME records
1922
- worksheets.each do |worksheet|
1922
+ def create_print_title_name_records(sorted_worksheets) #:nodoc:
1923
+ sorted_worksheets.each do |worksheet|
1923
1924
  index = worksheet.index
1924
1925
  rowmin = worksheet.title_rowmin
1925
1926
  rowmax = worksheet.title_rowmax
@@ -1970,6 +1971,7 @@ def store_names # :nodoc:
1970
1971
  end
1971
1972
  end
1972
1973
  end
1974
+ private :create_print_title_name_records
1973
1975
 
1974
1976
  ###############################################################################
1975
1977
  ###############################################################################
@@ -1980,7 +1982,7 @@ def store_names # :nodoc:
1980
1982
 
1981
1983
  ###############################################################################
1982
1984
  #
1983
- # _store_window1()
1985
+ # store_window1()
1984
1986
  #
1985
1987
  # Write Excel BIFF WINDOW1 record.
1986
1988
  #
@@ -2014,7 +2016,7 @@ def store_window1 #:nodoc:
2014
2016
 
2015
2017
  ###############################################################################
2016
2018
  #
2017
- # _store_boundsheet()
2019
+ # store_boundsheet()
2018
2020
  # my $sheetname = $_[0]; # Worksheet name
2019
2021
  # my $offset = $_[1]; # Location of worksheet BOF
2020
2022
  # my $type = $_[2]; # Worksheet type
@@ -2046,7 +2048,7 @@ def store_boundsheet(sheetname, offset, type, hidden, encoding) #:nodoc:
2046
2048
 
2047
2049
  ###############################################################################
2048
2050
  #
2049
- # _store_style()
2051
+ # store_style()
2050
2052
  # type = $_[0] # Built-in style
2051
2053
  # xf_index = $_[1] # Index to style XF
2052
2054
  #
@@ -2069,7 +2071,7 @@ def store_style(type, xf_index) #:nodoc:
2069
2071
 
2070
2072
  ###############################################################################
2071
2073
  #
2072
- # _store_num_format()
2074
+ # store_num_format()
2073
2075
  # my $format = $_[0]; # Custom format string
2074
2076
  # my $ifmt = $_[1]; # Format index code
2075
2077
  # my $encoding = $_[2]; # Char encoding for format string
@@ -2086,17 +2088,9 @@ def store_num_format(format, ifmt, encoding) #:nodoc:
2086
2088
  ruby_19 { format = convert_to_ascii_if_ascii(format) }
2087
2089
 
2088
2090
  # Handle utf8 strings
2089
- ruby_18 do
2090
- if format =~ NonAscii
2091
- format = utf8_to_16be(format)
2092
- encoding = 1
2093
- end
2094
- end
2095
- ruby_19 do
2096
- if format.encoding == Encoding::UTF_8
2097
- format = utf8_to_16be(format)
2098
- encoding = 1
2099
- end
2091
+ if is_utf8?(format)
2092
+ format = utf8_to_16be(format)
2093
+ encoding = 1
2100
2094
  end
2101
2095
 
2102
2096
  # Handle Unicode format strings.
@@ -2125,7 +2119,7 @@ def store_num_format(format, ifmt, encoding) #:nodoc:
2125
2119
 
2126
2120
  ###############################################################################
2127
2121
  #
2128
- # _store_1904()
2122
+ # store_1904()
2129
2123
  #
2130
2124
  # Write Excel 1904 record to indicate the date system in use.
2131
2125
  #
@@ -2144,7 +2138,7 @@ def store_1904 #:nodoc:
2144
2138
 
2145
2139
  ###############################################################################
2146
2140
  #
2147
- # _store_supbook()
2141
+ # store_supbook()
2148
2142
  #
2149
2143
  # Write BIFF record SUPBOOK to indicate that the workbook contains external
2150
2144
  # references, in our case, formula, print area and print title refs.
@@ -2165,7 +2159,7 @@ def store_supbook #:nodoc:
2165
2159
 
2166
2160
  ###############################################################################
2167
2161
  #
2168
- # _store_externsheet()
2162
+ # store_externsheet()
2169
2163
  #
2170
2164
  # Writes the Excel BIFF EXTERNSHEET record. These references are used by
2171
2165
  # formulas. TODO NAME record is required to define the print area and the
@@ -2198,8 +2192,8 @@ def store_externsheet # :nodoc:
2198
2192
  # Store the NAME record used for storing the print area, repeat rows, repeat
2199
2193
  # columns, autofilters and defined names.
2200
2194
  #
2201
- # TODO. This is a more generic version that will replace _store_name_short()
2202
- # and _store_name_long().
2195
+ # TODO. This is a more generic version that will replace store_name_short()
2196
+ # and store_name_long().
2203
2197
  #
2204
2198
  def store_name(name, encoding, sheet_index, formula) # :nodoc:
2205
2199
  ruby_19 { formula = convert_to_ascii_if_ascii(formula) }
@@ -2248,7 +2242,7 @@ def store_name(name, encoding, sheet_index, formula) # :nodoc:
2248
2242
 
2249
2243
  ###############################################################################
2250
2244
  #
2251
- # _store_name_short()
2245
+ # store_name_short()
2252
2246
  # index = shift # Sheet index
2253
2247
  # type = shift
2254
2248
  # ext_ref = shift # TODO
@@ -2309,7 +2303,7 @@ def store_name_short(index, type, ext_ref, rowmin, rowmax, colmin, colmax, hidde
2309
2303
 
2310
2304
  ###############################################################################
2311
2305
  #
2312
- # _store_name_long()
2306
+ # store_name_long()
2313
2307
  # my $index = shift; # Sheet index
2314
2308
  # my $type = shift;
2315
2309
  # my $ext_ref = shift; # TODO
@@ -2321,7 +2315,7 @@ def store_name_short(index, type, ext_ref, rowmin, rowmax, colmin, colmax, hidde
2321
2315
  #
2322
2316
  # Store the NAME record in the long format that is used for storing the repeat
2323
2317
  # rows and columns when both are specified. This share a lot of code with
2324
- # _store_name_short() but we use a separate method to keep the code clean.
2318
+ # store_name_short() but we use a separate method to keep the code clean.
2325
2319
  # Code abstraction for reuse can be carried too far, and I should know. ;-)
2326
2320
  #
2327
2321
  def store_name_long(index, type, ext_ref, rowmin, rowmax, colmin, colmax) #:nodoc:
@@ -2385,7 +2379,7 @@ def store_name_long(index, type, ext_ref, rowmin, rowmax, colmin, colmax)
2385
2379
 
2386
2380
  ###############################################################################
2387
2381
  #
2388
- # _store_palette()
2382
+ # store_palette()
2389
2383
  #
2390
2384
  # Stores the PALETTE biff record.
2391
2385
  #
@@ -2408,7 +2402,7 @@ def store_palette #:nodoc:
2408
2402
 
2409
2403
  ###############################################################################
2410
2404
  #
2411
- # _store_codepage()
2405
+ # store_codepage()
2412
2406
  #
2413
2407
  # Stores the CODEPAGE biff record.
2414
2408
  #
@@ -2423,7 +2417,7 @@ def store_codepage #:nodoc:
2423
2417
 
2424
2418
  ###############################################################################
2425
2419
  #
2426
- # _store_country()
2420
+ # store_country()
2427
2421
  #
2428
2422
  # Stores the COUNTRY biff record.
2429
2423
  #
@@ -2439,7 +2433,7 @@ def store_country #:nodoc:
2439
2433
 
2440
2434
  ###############################################################################
2441
2435
  #
2442
- # _store_hideobj()
2436
+ # store_hideobj()
2443
2437
  #
2444
2438
  # Stores the HIDEOBJ biff record.
2445
2439
  #
@@ -2452,7 +2446,7 @@ def store_hideobj #:nodoc:
2452
2446
  end
2453
2447
  private :store_hideobj
2454
2448
 
2455
- def store_common(record, length, *data)
2449
+ def store_common(record, length, *data) #:nodoc:
2456
2450
  header = [record, length].pack("vv")
2457
2451
  add_data = [*data].pack("v*")
2458
2452
 
@@ -2462,7 +2456,7 @@ def store_common(record, length, *data)
2462
2456
 
2463
2457
  ###############################################################################
2464
2458
  #
2465
- # _calculate_extern_sizes()
2459
+ # calculate_extern_sizes()
2466
2460
  #
2467
2461
  # We need to calculate the space required by the SUPBOOK, EXTERNSHEET and NAME
2468
2462
  # records so that it can be added to the BOUNDSHEET offsets.
@@ -2472,14 +2466,14 @@ def calculate_extern_sizes # :nodoc:
2472
2466
  length = 0
2473
2467
  index = 0
2474
2468
 
2475
- unless @defined_names.empty?
2469
+ unless defined_names.empty?
2476
2470
  index = 0
2477
2471
  key = "#{index}:#{index}"
2478
2472
 
2479
2473
  add_ext_refs(ext_refs, key) unless ext_refs.has_key?(key)
2480
2474
  end
2481
2475
 
2482
- @defined_names.each do |defined_name|
2476
+ defined_names.each do |defined_name|
2483
2477
  length += 19 + defined_name[:name].bytesize + defined_name[:formula].bytesize
2484
2478
  end
2485
2479
 
@@ -2535,26 +2529,26 @@ def calculate_extern_sizes # :nodoc:
2535
2529
  length
2536
2530
  end
2537
2531
 
2538
- def add_ext_refs(ext_refs, key)
2532
+ def add_ext_refs(ext_refs, key) #:nodoc:
2539
2533
  ext_refs[key] = ext_refs.keys.size
2540
2534
  end
2541
2535
  private :add_ext_refs
2542
2536
 
2543
2537
  ###############################################################################
2544
2538
  #
2545
- # _calculate_shared_string_sizes()
2539
+ # calculate_shared_string_sizes()
2546
2540
  #
2547
2541
  # Handling of the SST continue blocks is complicated by the need to include an
2548
2542
  # additional continuation byte depending on whether the string is split between
2549
2543
  # blocks or whether it starts at the beginning of the block. (There are also
2550
2544
  # additional complications that will arise later when/if Rich Strings are
2551
2545
  # supported). As such we cannot use the simple CONTINUE mechanism provided by
2552
- # the _add_continue() method in BIFFwriter.pm. Thus we have to make two passes
2546
+ # the add_continue() method in BIFFwriter.pm. Thus we have to make two passes
2553
2547
  # through the strings data. The first is to calculate the required block sizes
2554
- # and the second, in _store_shared_strings(), is to write the actual strings.
2548
+ # and the second, in store_shared_strings(), is to write the actual strings.
2555
2549
  # The first pass through the data is also used to calculate the size of the SST
2556
2550
  # and CONTINUE records for use in setting the BOUNDSHEET record offsets. The
2557
- # downside of this is that the same algorithm repeated in _store_shared_strings.
2551
+ # downside of this is that the same algorithm repeated in store_shared_strings.
2558
2552
  #
2559
2553
  def calculate_shared_string_sizes #:nodoc:
2560
2554
  strings = Array.new(@sinfo[:str_unique])
@@ -2570,12 +2564,12 @@ def calculate_shared_string_sizes #:nodoc:
2570
2564
  #
2571
2565
  # The SST blocks requires a specialised CONTINUE block, so we have to
2572
2566
  # ensure that the maximum data block size is less than the limit used by
2573
- # _add_continue() in BIFFwriter.pm. For simplicity we use the same size
2567
+ # add_continue() in BIFFwriter.pm. For simplicity we use the same size
2574
2568
  # for the SST and CONTINUE records:
2575
2569
  # 8228 : Maximum Excel97 block size
2576
2570
  # -4 : Length of block header
2577
2571
  # -8 : Length of additional SST header information
2578
- # -8 : Arbitrary number to keep within _add_continue() limit
2572
+ # -8 : Arbitrary number to keep within add_continue() limit
2579
2573
  # = 8208
2580
2574
  #
2581
2575
  continue_limit = 8208
@@ -2605,7 +2599,7 @@ def calculate_shared_string_sizes #:nodoc:
2605
2599
  split_string = 0
2606
2600
  while block_length >= continue_limit
2607
2601
  header_length, space_remaining, align, split_string =
2608
- _split_string_setup(encoding, split_string, continue_limit, written, continue)
2602
+ split_string_setup(encoding, split_string, continue_limit, written, continue)
2609
2603
 
2610
2604
  if space_remaining > header_length
2611
2605
  # Write as much as possible of the string in the current block
@@ -2667,7 +2661,7 @@ def calculate_shared_string_sizes #:nodoc:
2667
2661
  end
2668
2662
  private :calculate_shared_string_sizes
2669
2663
 
2670
- def _split_string_setup(encoding, split_string, continue_limit, written, continue)
2664
+ def split_string_setup(encoding, split_string, continue_limit, written, continue) #:nodoc:
2671
2665
  # We need to avoid the case where a string is continued in the first
2672
2666
  # n bytes that contain the string header information.
2673
2667
  header_length = 3 # Min string + header size -1
@@ -2697,15 +2691,15 @@ def _split_string_setup(encoding, split_string, continue_limit, written, continu
2697
2691
  end
2698
2692
  [header_length, space_remaining, align, split_string]
2699
2693
  end
2700
- private :_split_string_setup
2694
+ private :split_string_setup
2701
2695
 
2702
2696
  ###############################################################################
2703
2697
  #
2704
- # _store_shared_strings()
2698
+ # store_shared_strings()
2705
2699
  #
2706
2700
  # Write all of the workbooks strings into an indexed array.
2707
2701
  #
2708
- # See the comments in _calculate_shared_string_sizes() for more information.
2702
+ # See the comments in calculate_shared_string_sizes() for more information.
2709
2703
  #
2710
2704
  # We also use this routine to record the offsets required by the EXTSST table.
2711
2705
  # In order to do this we first identify the first string in an EXTSST bucket
@@ -2726,7 +2720,7 @@ def store_shared_strings #:nodoc:
2726
2720
  continue = 0
2727
2721
 
2728
2722
  # The SST and CONTINUE block sizes have been pre-calculated by
2729
- # _calculate_shared_string_sizes()
2723
+ # calculate_shared_string_sizes()
2730
2724
  block_sizes = @str_block_sizes
2731
2725
 
2732
2726
  # The SST record is required even if it contains no strings. Thus we will
@@ -2785,7 +2779,7 @@ def store_shared_strings #:nodoc:
2785
2779
  split_string = 0
2786
2780
  while block_length >= continue_limit
2787
2781
  header_length, space_remaining, align, split_string =
2788
- _split_string_setup(encoding, split_string, continue_limit, written, continue)
2782
+ split_string_setup(encoding, split_string, continue_limit, written, continue)
2789
2783
 
2790
2784
  if space_remaining > header_length
2791
2785
  # Write as much as possible of the string in the current block
@@ -2857,7 +2851,7 @@ def store_shared_strings #:nodoc:
2857
2851
 
2858
2852
  ###############################################################################
2859
2853
  #
2860
- # _calculate_extsst_size
2854
+ # calculate_extsst_size
2861
2855
  #
2862
2856
  # The number of buckets used in the EXTSST is between 0 and 128. The number of
2863
2857
  # strings per bucket (bucket size) has a minimum value of 8 and a theoretical
@@ -2884,9 +2878,9 @@ def calculate_extsst_size #:nodoc:
2884
2878
 
2885
2879
  ###############################################################################
2886
2880
  #
2887
- # _store_extsst
2881
+ # store_extsst
2888
2882
  #
2889
- # Write EXTSST table using the offsets calculated in _store_shared_strings().
2883
+ # Write EXTSST table using the offsets calculated in store_shared_strings().
2890
2884
  #
2891
2885
  def store_extsst #:nodoc:
2892
2886
  offsets = @extsst_offsets
@@ -2912,7 +2906,7 @@ def store_extsst #:nodoc:
2912
2906
 
2913
2907
  ###############################################################################
2914
2908
  #
2915
- # _add_mso_drawing_group()
2909
+ # add_mso_drawing_group()
2916
2910
  #
2917
2911
  # Write the MSODRAWINGGROUP record that keeps track of the Escher drawing
2918
2912
  # objects in the file such as images, comments and filters.
@@ -2943,7 +2937,7 @@ def add_mso_drawing_group #:nodoc:
2943
2937
 
2944
2938
  ###############################################################################
2945
2939
  #
2946
- # _add_mso_drawing_group_continue()
2940
+ # add_mso_drawing_group_continue()
2947
2941
  #
2948
2942
  # See first the WriteExcel::BIFFwriter::_add_continue() method.
2949
2943
  #
@@ -2962,7 +2956,7 @@ def add_mso_drawing_group_continue(data) #:nodoc:
2962
2956
  continue = 0x003C # Record identifier
2963
2957
  block_count = 1
2964
2958
 
2965
- # Ignore the base class _add_continue() method.
2959
+ # Ignore the base class add_continue() method.
2966
2960
  @ignore_continue = 1
2967
2961
 
2968
2962
  # Case 1 above. Just return the data as it is.
@@ -2995,12 +2989,12 @@ def add_mso_drawing_group_continue(data) #:nodoc:
2995
2989
  header = [continue, data.bytesize].pack("vv")
2996
2990
  append(header, data)
2997
2991
 
2998
- # Turn the base class _add_continue() method back on.
2992
+ # Turn the base class add_continue() method back on.
2999
2993
  @ignore_continue = 0
3000
2994
  end
3001
2995
  private :add_mso_drawing_group_continue
3002
2996
 
3003
- def devide_string(string, nth)
2997
+ def devide_string(string, nth) #:nodoc:
3004
2998
  first_string = string[0, nth]
3005
2999
  latter_string = string[nth, string.size - nth]
3006
3000
  [first_string, latter_string]
@@ -3009,7 +3003,7 @@ def devide_string(string, nth)
3009
3003
 
3010
3004
  ###############################################################################
3011
3005
  #
3012
- # _store_mso_dgg_container()
3006
+ # store_mso_dgg_container()
3013
3007
  #
3014
3008
  # Write the Escher DggContainer record that is part of MSODRAWINGGROUP.
3015
3009
  #
@@ -3026,7 +3020,7 @@ def store_mso_dgg_container #:nodoc:
3026
3020
 
3027
3021
  ###############################################################################
3028
3022
  #
3029
- # _store_mso_dgg()
3023
+ # store_mso_dgg()
3030
3024
  # my $max_spid = $_[0];
3031
3025
  # my $num_clusters = $_[1];
3032
3026
  # my $shapes_saved = $_[2];
@@ -3058,7 +3052,7 @@ def store_mso_dgg(max_spid, num_clusters, shapes_saved, drawings_saved, clusters
3058
3052
 
3059
3053
  ###############################################################################
3060
3054
  #
3061
- # _store_mso_bstore_container()
3055
+ # store_mso_bstore_container()
3062
3056
  #
3063
3057
  # Write the Escher BstoreContainer record that is part of MSODRAWINGGROUP.
3064
3058
  #
@@ -3077,7 +3071,7 @@ def store_mso_bstore_container #:nodoc:
3077
3071
 
3078
3072
  ###############################################################################
3079
3073
  #
3080
- # _store_mso_images()
3074
+ # store_mso_images()
3081
3075
  # ref_count = $_[0]
3082
3076
  # image_type = $_[1]
3083
3077
  # image = $_[2]
@@ -3109,7 +3103,7 @@ def store_mso_images(ref_count, image_type, image, size, checksum1, checksum2)
3109
3103
 
3110
3104
  ###############################################################################
3111
3105
  #
3112
- # _store_mso_blip_store_entry()
3106
+ # store_mso_blip_store_entry()
3113
3107
  # ref_count = $_[0]
3114
3108
  # image_type = $_[1]
3115
3109
  # size = $_[2]
@@ -3140,7 +3134,7 @@ def store_mso_blip_store_entry(ref_count, image_type, size, checksum1) #:n
3140
3134
 
3141
3135
  ###############################################################################
3142
3136
  #
3143
- # _store_mso_blip()
3137
+ # store_mso_blip()
3144
3138
  # image_type = $_[0]
3145
3139
  # image_data = $_[1]
3146
3140
  # size = $_[2]
@@ -3172,7 +3166,7 @@ def store_mso_blip(image_type, image_data, size, checksum1, checksum2) #:n
3172
3166
 
3173
3167
  ###############################################################################
3174
3168
  #
3175
- # _store_mso_opt()
3169
+ # store_mso_opt()
3176
3170
  #
3177
3171
  # Write the Escher Opt record that is part of MSODRAWINGGROUP.
3178
3172
  #
@@ -3191,7 +3185,7 @@ def store_mso_opt #:nodoc:
3191
3185
 
3192
3186
  ###############################################################################
3193
3187
  #
3194
- # _store_mso_split_menu_colors()
3188
+ # store_mso_split_menu_colors()
3195
3189
  #
3196
3190
  # Write the Escher SplitMenuColors record that is part of MSODRAWINGGROUP.
3197
3191
  #
@@ -3208,8 +3202,9 @@ def store_mso_split_menu_colors #:nodoc:
3208
3202
  end
3209
3203
  private :store_mso_split_menu_colors
3210
3204
 
3211
- def cleanup
3205
+ def cleanup #:nodoc:
3212
3206
  super
3213
3207
  sheets.each { |sheet| sheet.cleanup }
3214
3208
  end
3209
+ private :cleanup
3215
3210
  end