robust_excel_ole 1.26 → 1.31

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog +17 -0
  3. data/README.rdoc +12 -5
  4. data/benchmarking/reo_example.rb +1 -1
  5. data/benchmarking/reo_example1.rb +1 -1
  6. data/benchmarking/reo_example2.rb +1 -1
  7. data/bin/jreo +20 -1
  8. data/bin/reo +20 -1
  9. data/docs/README_open.rdoc +8 -4
  10. data/docs/README_sheet.rdoc +1 -7
  11. data/examples/introductory_examples/example_open.rb +11 -0
  12. data/lib/robust_excel_ole.rb +19 -16
  13. data/lib/robust_excel_ole/base.rb +5 -0
  14. data/lib/robust_excel_ole/bookstore.rb +1 -1
  15. data/lib/robust_excel_ole/cell.rb +1 -1
  16. data/lib/robust_excel_ole/cygwin.rb +2 -0
  17. data/lib/robust_excel_ole/excel.rb +12 -22
  18. data/lib/robust_excel_ole/general.rb +270 -206
  19. data/lib/robust_excel_ole/list_object.rb +18 -115
  20. data/lib/robust_excel_ole/list_row.rb +128 -0
  21. data/lib/robust_excel_ole/range.rb +5 -1
  22. data/lib/robust_excel_ole/range_owners.rb +4 -71
  23. data/lib/robust_excel_ole/version.rb +1 -1
  24. data/lib/robust_excel_ole/workbook.rb +71 -29
  25. data/lib/robust_excel_ole/worksheet.rb +107 -22
  26. data/lib/spec_helper.rb +1 -1
  27. data/spec/address_tool_spec.rb +2 -2
  28. data/spec/base_spec.rb +19 -17
  29. data/spec/bookstore_spec.rb +1 -1
  30. data/spec/cell_spec.rb +1 -1
  31. data/spec/cygwin_spec.rb +1 -1
  32. data/spec/data/more_data/workbook.xls +0 -0
  33. data/spec/excel_spec.rb +1 -1
  34. data/spec/general_spec.rb +64 -7
  35. data/spec/list_object_spec.rb +85 -20
  36. data/spec/range_spec.rb +1 -14
  37. data/spec/spec_helper.rb +1 -1
  38. data/spec/workbook_spec.rb +12 -12
  39. data/spec/workbook_specs/workbook_all_spec.rb +8 -28
  40. data/spec/workbook_specs/workbook_close_spec.rb +1 -1
  41. data/spec/workbook_specs/workbook_misc_spec.rb +33 -33
  42. data/spec/workbook_specs/workbook_open_spec.rb +56 -5
  43. data/spec/workbook_specs/workbook_save_spec.rb +1 -1
  44. data/spec/workbook_specs/workbook_sheet_spec.rb +1 -1
  45. data/spec/workbook_specs/workbook_subclass_spec.rb +1 -1
  46. data/spec/workbook_specs/workbook_unobtr_spec.rb +273 -115
  47. data/spec/worksheet_spec.rb +51 -19
  48. metadata +3 -5
  49. data/jreo.bat +0 -3
  50. data/lib/reo_console.rb +0 -68
  51. data/reo.bat +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2553a7622f9092b5067ad3f7e945d57a1dbfa6e540716b326c6b684a351cf79
4
- data.tar.gz: e623c4a2f3e22ef1da88b6475d7f6dc277c9f3f4581db27427fd9ca6aa400f24
3
+ metadata.gz: 304ee26bf15359eec5e54ac846203b60f3d7419e54779ced816182f76f6e9b46
4
+ data.tar.gz: 0ea8a4d763d10b286cd29610261b815ca51308cb364483935c5c396fa31e2c67
5
5
  SHA512:
6
- metadata.gz: 9056cec7af1bf9c6c04ab2df83dd080bb63308f5c5a7d6af13286090d357441928d7dcb2dde2371940e36729fafb26460098d2063254f8809796a9dde87ddc85
7
- data.tar.gz: d036c741ef593695e0fecfd8f1e34b1db5bec0e7e2430b5a88f1e16a297a804b1a9d95c8bc847bc993f0a1ea4b666cd56db200cc9cdfec38078dab6c5b4ef59b
6
+ metadata.gz: ae94a7357c87e0069e15e279a0eb420df939840192fc2e674f8e3c1890bebdaa7c49d37e0d8a888939f8009109fc7fabf0105e7b76f6b75f168431cb58d2e0e1
7
+ data.tar.gz: 450ebbad0840bd557c652cc2fa9027dee4a45114a6d3b8ea0065fd5120e9b916ad26ad63a1f97088bb148f1dc07cff7fd9cdf8c9b956e6a0ee2295be4434dec2
data/Changelog CHANGED
@@ -1,6 +1,23 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.31] 2021-14-01
5
+
6
+ ### Added
7
+ - Worksheet#table
8
+
9
+ ## [1.30] 2020-18-11
10
+
11
+ ## [1.29] 2020-05-11
12
+
13
+ ### Added
14
+ - Workbook.open can also take a Pathname object
15
+ - General#init_reo_for_win32ole
16
+
17
+ ## [1.28] 2020-23-10
18
+
19
+ ## [1.27] 2020-16-10
20
+
4
21
  ## [1.26] 2020-09-10
5
22
 
6
23
  ### Added
@@ -320,7 +320,11 @@ For more details about reading and writing contents of cells and ranges see {REA
320
320
 
321
321
  === More features
322
322
 
323
- The ruby shell 'pry' allows, among other useful things, to change the value of 'self' in the console. For example,
323
+ 1. The method +General.change_current_binding+ allows to change the value of self within the current binding, while preserving the local variables, without starting another repl. Assume, +object+ shall be the self, then you would put
324
+
325
+ General.change_current_binding(object)
326
+
327
+ Without this method, the ruby shell 'pry' allows to change the value of 'self' in the console as well, e.g.
324
328
 
325
329
  object.pry
326
330
 
@@ -328,13 +332,16 @@ or
328
332
 
329
333
  cd object
330
334
 
331
- will set +object+ to self. However, this command also starts another pry repl (with another binding). Moreover, local variables in the previous binding are forgotten.
335
+ However, this command also starts another pry repl (with another binding). Moreover, local variables in the previous binding are forgotten.
336
+
337
+
338
+ 2. The class Win32Ole is being extended such that RobustExcelOle methods can be applied to Win32Ole objects. As mentioned above, the RobustExcelOle objects are wrapper of corresponding WIN32OLE objects. So the RobustExcelOle objects and their wrapped Win32Ole objects are interchangeable. One example would be
332
339
 
333
- The method +General.change_current_binding+ allows to change the value of self within the current binding, while preserving the local variables, without starting another repl.
340
+ range.ole_range.copy([4,3])
334
341
 
335
- General.change_current_binding
342
+ Likewise it is possible to convert ("type-lift") Win32Ole objects into the corresponding RobustExcelOle object, using the method +to_reo+. It is a refinement of the class WIN32OLE. So you can write
336
343
 
337
- You can convert some Win32Ole objects into a RobustExcelOle object.
344
+ using ToReoRefinement
338
345
 
339
346
  range = sheet.Names.Item("firstcell").to_reo
340
347
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '../lib/robust_excel_ole')
1
+ require_relative '../lib/robust_excel_ole'
2
2
 
3
3
  start_time = Time.now
4
4
 
@@ -1,5 +1,5 @@
1
1
  #require 'robust_excel_ole'
2
- require File.join(File.dirname(__FILE__), '../lib/robust_excel_ole')
2
+ require_relative '../lib/robust_excel_ole'
3
3
 
4
4
  start_time = Time.now
5
5
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '../lib/robust_excel_ole')
1
+ require_relative '../lib/robust_excel_ole'
2
2
 
3
3
  start_time = Time.now
4
4
 
data/bin/jreo CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- jruby -*-
3
3
 
4
4
  require 'pry'
5
- require '../robust_excel_ole/lib/robust_excel_ole'
5
+ require_relative '../lib/robust_excel_ole'
6
6
 
7
7
  include REO
8
8
  include General
@@ -15,10 +15,29 @@ Pry.config.prompt_name = "REO "
15
15
  #Pry.config.history_save = true
16
16
  #Pry.editor = 'notepad' # 'subl', 'vi'
17
17
 
18
+ prompt_proc1 = proc { |target_self, nest_level, pry|
19
+ "[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
20
+ }
21
+
22
+ prompt_proc2 = proc { |target_self, nest_level, pry|
23
+ "[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self.inspect.gsub(/\"/, ''))})})#{":#{nest_level}" unless nest_level.zero?}* "
24
+ }
25
+
26
+ Pry.config.prompt = if RUBY_PLATFORM =~ /java/
27
+ [prompt_proc1, prompt_proc2]
28
+ else
29
+ Pry::Prompt.new(
30
+ "REO",
31
+ "The RobustExcelOle Prompt. Besides the standard information it puts the current object",
32
+ [prompt_proc1, prompt_proc2]
33
+ )
34
+ end
35
+
18
36
  hooks = Pry::Hooks.new
19
37
 
20
38
  hooks.add_hook :when_started, :hook12 do
21
39
  puts 'REO console started'
22
40
  puts
23
41
  end
42
+
24
43
  Pry.start(nil, hooks: hooks)
data/bin/reo CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- ruby -*-
3
3
 
4
4
  require 'pry'
5
- require '../robust_excel_ole/lib/robust_excel_ole'
5
+ require_relative '../lib/robust_excel_ole'
6
6
 
7
7
  include REO
8
8
  include General
@@ -15,10 +15,29 @@ Pry.config.prompt_name = "REO "
15
15
  #Pry.config.history_save = true
16
16
  #Pry.editor = 'notepad' # 'subl', 'vi'
17
17
 
18
+ prompt_proc1 = proc { |target_self, nest_level, pry|
19
+ "[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
20
+ }
21
+
22
+ prompt_proc2 = proc { |target_self, nest_level, pry|
23
+ "[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
24
+ }
25
+
26
+ Pry.config.prompt = if RUBY_PLATFORM =~ /java/
27
+ [prompt_proc1, prompt_proc2]
28
+ else
29
+ Pry::Prompt.new(
30
+ "REO",
31
+ "The RobustExcelOle Prompt. Besides the standard information it puts the current object",
32
+ [prompt_proc1, prompt_proc2]
33
+ )
34
+ end
35
+
18
36
  hooks = Pry::Hooks.new
19
37
 
20
38
  hooks.add_hook :when_started, :hook12 do
21
39
  puts 'REO console started'
22
40
  puts
23
41
  end
42
+
24
43
  Pry.start(nil, hooks: hooks)
@@ -17,6 +17,11 @@ The semantics is similar to, e.g., +File.open+.
17
17
  # do something
18
18
  end
19
19
 
20
+ You can provide the filename as a string (as above) or as Pathname object.
21
+
22
+ pathname = Pathname('spec/data/workbook.xls')
23
+ workbook = Workbook.open(pathname)
24
+
20
25
  The options are the following:
21
26
 
22
27
  +:default+:: if the workbook was already open, then use the properties of this workbook.otherwise use the properties stated in +:default+
@@ -195,12 +200,11 @@ The method +unobtrusively+ enables the user to read or modify a workbook, no mat
195
200
 
196
201
  Options are the following:
197
202
 
198
- +:if_closed+:: the Excel instance in which to open the workbook, if it was closed (default: +:current+). (Note: this option works workbooks opened via RobustExcelOle only.)
199
-
200
203
  +:read_only+:: Whether the workbook shall be forced to be open in ReadOnly mode
201
- +:writable+:: Whether changes in the workbook shall be saved
202
-
204
+ +:writable+:: Whether changes in the workbook shall be saved and the workbook shall be opened in ReadOnly mode by default (i.e., when the workbook was not open before) (default: true)
203
205
  +:keep_open+:: Whether the workbook shall be open after unobtrusively opening (default: false)
206
+ +:if_closed+:: the Excel instance in which to open the workbook, if it was closed (default: +:current+).
207
+ (Note: this option works workbooks opened via RobustExcelOle only.)
204
208
 
205
209
  There are the class method and the instance method of +unobtrusively+. Here is an example of the class method:
206
210
 
@@ -92,17 +92,11 @@ The methods Worksheet#each, Worksheet#each_row and Worksheet#each_column enable
92
92
  # do something with column
93
93
  end
94
94
 
95
- The method Worksheet#values yields all cell values of the used range of the worksheet into a 2-dimensional array. For example:
95
+ The method Worksheet#values yields a 2-dimensional array that contains the values in each row, e.g.
96
96
 
97
97
  worksheet.values
98
98
  => [["foo", "workbook", "sheet1"], ["foo", nil, "foobaaa"], ["matz", "is", "nice"]]
99
99
 
100
- The method Worksheet#each_rowvalue enables to access the values of each row.
101
-
102
- worksheet.each_rowvalue do |row_values|
103
- # do something with the row_values
104
- end
105
-
106
100
  You access a range of a row by giving the number of the row, and optionally, the range of the cell numbers.
107
101
 
108
102
  worksheet.row_range(1) # => first row
@@ -18,7 +18,18 @@ puts "open a workbook"
18
18
  book = Workbook.open(simple_file)
19
19
  puts "make it visible"
20
20
  book.visible = true
21
+
22
+ ole_workbook = book.ole_workbook
23
+ puts "ole_workbook: #{ole_workbook}"
24
+ sheet = ole_workbook.sheet(1)
25
+ puts "sheet: #{sheet}"
26
+
27
+ using ToReoRefinement
21
28
  puts "book: #{book}"
29
+ ole_workbook = book.ole_workbook
30
+ puts "ole_workbook: #{ole_workbook.inspect}"
31
+ upliftet_ole_workbook = ole_workbook.to_reo
32
+ puts "upliftet_ole_workbook: #{upliftet_ole_workbook.inspect}"
22
33
  # open a workbook in a new Excel instance
23
34
  puts "open the workbook in a new Excel instance and make it visible"
24
35
  book2 = Workbook.open(another_simple_file, :default => {:excel => :new}, :visible => true)
@@ -1,22 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+
1
3
  if RUBY_PLATFORM =~ /java/
2
4
  require 'jruby-win32ole'
3
5
  else
4
6
  require 'win32ole'
5
7
  end
6
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/base')
7
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/general')
8
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/vba_objects')
9
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/range_owners')
10
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/address_tool')
11
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/excel')
12
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/bookstore')
13
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/workbook')
14
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/worksheet')
15
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/cell')
16
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/range')
17
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/list_object')
18
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLATFORM =~ /cygwin/
19
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
20
8
 
21
- #include RobustExcelOle
22
- include General
9
+ require_relative 'robust_excel_ole/general'
10
+ require_relative 'robust_excel_ole/base'
11
+ require_relative 'robust_excel_ole/vba_objects'
12
+ require_relative 'robust_excel_ole/range_owners'
13
+ require_relative 'robust_excel_ole/address_tool'
14
+ require_relative 'robust_excel_ole/excel'
15
+ require_relative 'robust_excel_ole/bookstore'
16
+ require_relative 'robust_excel_ole/workbook'
17
+ require_relative 'robust_excel_ole/worksheet'
18
+ require_relative 'robust_excel_ole/cell'
19
+ require_relative 'robust_excel_ole/range'
20
+ require_relative 'robust_excel_ole/list_row'
21
+ require_relative 'robust_excel_ole/list_object'
22
+ require_relative 'robust_excel_ole/cygwin' if RUBY_PLATFORM =~ /cygwin/
23
+ require_relative 'robust_excel_ole/version'
24
+
25
+ General.init_reo_for_win32ole
@@ -65,6 +65,8 @@ module RobustExcelOle
65
65
 
66
66
  class Base
67
67
 
68
+ include General
69
+
68
70
  # @private
69
71
  def own_methods
70
72
  (self.methods - Object.methods).sort
@@ -110,3 +112,6 @@ module RobustExcelOle
110
112
  end
111
113
 
112
114
  end
115
+
116
+ REO = RobustExcelOle
117
+
@@ -4,7 +4,7 @@ module RobustExcelOle
4
4
 
5
5
  # @private
6
6
  class Bookstore < Base
7
-
7
+
8
8
  def initialize
9
9
  @filename2books ||= Hash.new { |hash, key| hash[key] = [] }
10
10
  @hidden_excel_instance = nil
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- require File.join(File.dirname(__FILE__), './range')
3
+ require_relative 'range'
4
4
 
5
5
  module RobustExcelOle
6
6
 
@@ -1,3 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
1
3
  module RobustExcelOle
2
4
  module Cygwin
3
5
  require 'Win32API'
@@ -15,6 +15,7 @@ module RobustExcelOle
15
15
  # See https://docs.microsoft.com/en-us/office/vba/api/excel.application(object)#methods
16
16
 
17
17
  class Excel < VbaObjects
18
+
18
19
  attr_reader :ole_excel
19
20
  attr_reader :properties
20
21
  attr_reader :address_tool
@@ -370,7 +371,7 @@ module RobustExcelOle
370
371
  number = 0
371
372
  WIN32OLE.connect('winmgmts:\\\\.').InstancesOf('win32_process').each do |p|
372
373
  begin
373
- if p.name == 'EXCEL.EXE'
374
+ if p.Name == 'EXCEL.EXE'
374
375
  Process.kill('KILL', p.processid)
375
376
  number += 1
376
377
  end
@@ -384,7 +385,7 @@ module RobustExcelOle
384
385
 
385
386
  def self.excels_number
386
387
  processes = WIN32OLE.connect('winmgmts:\\\\.').InstancesOf('win32_process')
387
- processes.select { |p| p.name == 'EXCEL.EXE' }.size
388
+ processes.select { |p| p.Name == 'EXCEL.EXE' }.size
388
389
  end
389
390
 
390
391
  def self.known_excels_number
@@ -417,7 +418,7 @@ module RobustExcelOle
417
418
  result.Visible # send any method, just to see if it responds
418
419
  rescue
419
420
  trace 'dead excel ' + (begin
420
- "Window-handle = #{result.HWnd}"
421
+ "Window-handle = #{result.Hwnd}"
421
422
  rescue
422
423
  'without window handle'
423
424
  end)
@@ -471,13 +472,13 @@ module RobustExcelOle
471
472
  pid2excel[pid] = excel
472
473
  end
473
474
  processes = WIN32OLE.connect('winmgmts:\\\\.').InstancesOf('win32_process')
474
- processes.select { |p| Excel.new(pid2excel[p.processid]) if p.name == 'EXCEL.EXE' && pid2excel.include?(p.processid) }
475
+ processes.select { |p| Excel.new(pid2excel[p.ProcessId]) if p.Name == 'EXCEL.EXE' && pid2excel.include?(p.ProcessId) }
475
476
  result = []
476
477
  processes.each do |p|
477
- next unless p.name == 'EXCEL.EXE'
478
+ next unless p.Name == 'EXCEL.EXE'
478
479
 
479
- if pid2excel.include?(p.processid)
480
- excel = pid2excel[p.processid]
480
+ if pid2excel.include?(p.ProcessId)
481
+ excel = pid2excel[p.ProcessId]
481
482
  result << excel
482
483
  end
483
484
  # how to connect to an (interactively opened) Excel instance and get a WIN32OLE object?
@@ -684,21 +685,7 @@ module RobustExcelOle
684
685
  # Win32API.new("user32","SetForegroundWindow","","I").call
685
686
  # end
686
687
  end
687
-
688
- # returns the value of a range
689
- # @param [String] name the name of a range
690
- # @returns [Variant] the value of the range
691
- def [] name
692
- namevalue_glob(name)
693
- end
694
-
695
- # sets the value of a range
696
- # @param [String] name the name of the range
697
- # @param [Variant] value the contents of the range
698
- def []=(name, value)
699
- set_namevalue_glob(name, value)
700
- end
701
-
688
+
702
689
  # @private
703
690
  # returns active workbook
704
691
  def workbook
@@ -717,6 +704,9 @@ module RobustExcelOle
717
704
  to_s
718
705
  end
719
706
 
707
+ using ParentRefinement
708
+ using StringRefinement
709
+
720
710
  # @private
721
711
  def self.workbook_class
722
712
  @workbook_class ||= begin
@@ -1,78 +1,163 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require 'pathname'
2
3
 
3
- module General
4
+ # @private
5
+ #class WIN32OLE
6
+ module ToReoRefinement
4
7
 
5
- IS_JRUBY_PLATFORM = (RUBY_PLATFORM =~ /java/)
6
- ::EXPANDPATH_JRUBY_BUG = IS_JRUBY_PLATFORM && true
7
- ::CONNECT_JRUBY_BUG = IS_JRUBY_PLATFORM && true
8
- ::COPYSHEETS_JRUBY_BUG = IS_JRUBY_PLATFORM && true
9
- ::ERRORMESSAGE_JRUBY_BUG = IS_JRUBY_PLATFORM && true
10
- ::CONNECT_EXCEL_JRUBY_BUG = IS_JRUBY_PLATFORM && true
11
- ::RANGES_JRUBY_BUG = IS_JRUBY_PLATFORM && true
12
-
13
- @private
14
- NetworkDrive = Struct.new(:drive_letter, :network_name) do
8
+ refine WIN32OLE do
15
9
 
16
- def self.get_all(drives)
17
- ndrives = []
18
- count = drives.Count
19
- (0..(count - 1)).step(2) do |i|
20
- ndrives << NetworkDrive.new( drives.Item(i), drives.Item(i + 1).tr('\\','/'))
10
+ # type-lifting WIN32OLE objects to RobustExcelOle objects
11
+ def to_reo
12
+ General.class2method.each do |element|
13
+ classname = element.first.first
14
+ method = element.first.last
15
+ begin
16
+ self.send(method)
17
+ if classname == RobustExcelOle::Range && self.Rows.Count == 1 && self.Columns.Count == 1
18
+ return Cell.new(self, self.Parent)
19
+ else
20
+ return classname.new(self)
21
+ end
22
+ rescue
23
+ next
24
+ end
21
25
  end
22
- ndrives
26
+ raise TypeREOError, "given object cannot be type-lifted to a RobustExcelOle object"
23
27
  end
24
28
 
25
29
  end
26
30
 
27
- @private
28
- def hostnameshare2networkpath(filename)
29
- return filename unless filename[0,2] == "//"
30
- network = WIN32OLE.new('WScript.Network')
31
- drives = network.enumnetworkdrives
32
- network_drives = NetworkDrive.get_all(drives)
33
- f_c = filename.dup
34
- network_drive = network_drives.find do |d|
35
- e = f_c.sub!(d.network_name,d.drive_letter)
36
- return e if e
37
- end
38
- filename
39
- end
31
+ end
40
32
 
41
- # @private
42
- def absolute_path(file)
43
- return file if file[0,2] == "//"
44
- file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
45
- file = File.expand_path(file)
46
- file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
47
- WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file) #.tr('/','\\')
48
- end
33
+ # @private
34
+ class WIN32OLE
49
35
 
50
- # @private
51
- def canonize(filename)
52
- raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
53
- filename = hostnameshare2networkpath(filename)
54
- normalize(filename) if filename
55
- end
36
+ include Enumerable
56
37
 
57
- # @private
58
- def normalize(path)
59
- return unless path
60
- path = path.gsub('/./', '/') + '/'
61
- path = path.gsub(/[\/\\]+/, '/')
62
- nil while path.gsub!(/(\/|^)(?!\.\.?)([^\/]+)\/\.\.\//, '\1')
63
- path = path.chomp('/')
64
- path
65
- end
38
+ end
39
+
40
+ # @private
41
+ module FindAllIndicesRefinement
42
+
43
+ refine Array do
44
+
45
+ def find_all_indices elem
46
+ found, index, result = -1, -1, []
47
+ while found
48
+ found = self[index+1..-1].index(elem)
49
+ if found
50
+ index = index + found + 1
51
+ result << index
52
+ end
53
+ end
54
+ result
55
+ end
66
56
 
67
- def change_current_binding(current_object)
68
- Pry.change_current_binding(current_object)
69
57
  end
70
58
 
71
- module_function :absolute_path, :canonize, :normalize, :change_current_binding
59
+ end
60
+
61
+ # @private
62
+ module StringRefinement
63
+
64
+ refine String do
65
+
66
+ def / path_part
67
+ if empty?
68
+ path_part
69
+ else
70
+ if path_part.nil? || path_part.empty?
71
+ self
72
+ else
73
+ begin
74
+ path_part = path_part.strip
75
+ (path_part =~ /^(\/|([A-Z]:\/))/i) ? path_part : (self.chomp('/') + '/' + path_part)
76
+ rescue TypeError
77
+ raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def replace_umlauts
84
+ word = self.force_encoding('iso-8859-1').encode('utf-8')
85
+ #word = self.encode("UTF-8")
86
+ #word = self.encode("UTF-8", "Windows-1252")
87
+ word.gsub('ä','ae').gsub('Ä','Ae').gsub('ö','oe').gsub('Ö','Oe').gsub('ü','ue').gsub('Ü','Ue')
88
+ word.gsub('ß','ss').gsub('²','2').gsub('³','3')
89
+ #word.gsub("\x84",'ae').gsub("\x8E",'Ae').gsub("\x94",'oe').gsub("\x99",'Oe').gsub("\x81",'ue').gsub("\x9A",'Ue')
90
+ #word.gsub("\xE1",'ss').gsub("\xFD",'2').gsub("\xFC",'3')
91
+ word
92
+ end
93
+
94
+ # taken from http://apidock.com/rails/ActiveSupport/Inflector/underscore
95
+ def underscore
96
+ word = gsub('::', '/')
97
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
98
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
99
+ word.tr!('-', '_')
100
+ word.downcase!
101
+ word
102
+ end
72
103
 
104
+ # taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
105
+ # File activesupport/lib/active_support/inflector/methods.rb, line 226
106
+ def constantize # (camel_cased_word)
107
+ names = split('::')
108
+
109
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
110
+ Object.const_get(self) if names.empty?
111
+
112
+ # Remove the first blank element in case of '::ClassName' notation.
113
+ names.shift if names.size > 1 && names.first.empty?
114
+
115
+ names.inject(Object) do |constant, name|
116
+ if constant == Object
117
+ constant.const_get(name)
118
+ else
119
+ candidate = constant.const_get(name)
120
+ next candidate if constant.const_defined?(name)
121
+ next candidate unless Object.const_defined?(name)
122
+
123
+ # Go down the ancestors to check it it's owned
124
+ # directly before we reach Object or the end of ancestors.
125
+ constant = constant.ancestors.inject do |const, ancestor|
126
+ break const if ancestor == Object
127
+ break ancestor if ancestor.const_defined?(name)
128
+
129
+ const
130
+ end
131
+
132
+ # owner is in Object, so raise
133
+ constant.const_get(name)
134
+ end
135
+ end
136
+ end
137
+ end
73
138
  end
74
139
 
75
140
  # @private
141
+ module ParentRefinement
142
+
143
+ using StringRefinement
144
+
145
+ # taken from http://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Module.html#M000806
146
+ refine Module do
147
+
148
+ def parent_name
149
+ unless defined? @parent_name
150
+ @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
151
+ end
152
+ @parent_name
153
+ end
154
+
155
+ def parent
156
+ parent_name ? parent_name.constantize : Object
157
+ end
158
+ end
159
+ end
160
+
76
161
  class Integer
77
162
 
78
163
  alias old_spaceship <=>
@@ -102,183 +187,164 @@ class Array
102
187
  end
103
188
  end
104
189
 
105
- def find_each_index find
106
- found, index, q = -1, -1, []
107
- while found
108
- found = self[index+1..-1].index(find)
109
- if found
110
- index = index + found + 1
111
- q << index
112
- end
113
- end
114
- q
115
- end
116
190
  end
117
191
 
118
- # @private
119
- class WIN32OLE
120
192
 
121
- include Enumerable
122
-
123
- # type-lifting WIN32OLE objects to RobustExcelOle objects
124
- def to_reo
125
- class2method = [
126
- {Excel => :Hwnd},
127
- {Workbook => :FullName},
128
- {Worksheet => :UsedRange},
129
- {RobustExcelOle::Range => :Row},
130
- {ListObject => :ListRows}
131
- ]
132
- class2method.each do |element|
133
- classname = element.first.first
134
- method = element.first.last
135
- begin
136
- self.send(method)
137
- if classname == RobustExcelOle::Range && self.Rows.Count == 1 && self.Columns.Count == 1
138
- return Cell.new(self, self.Parent)
139
- else
140
- return classname.new(self)
141
- end
142
- rescue
143
- next
193
+ module General
194
+
195
+ using ToReoRefinement
196
+
197
+ IS_JRUBY_PLATFORM = (RUBY_PLATFORM =~ /java/)
198
+ ::EXPANDPATH_JRUBY_BUG = IS_JRUBY_PLATFORM && true
199
+ ::CONNECT_JRUBY_BUG = IS_JRUBY_PLATFORM && true
200
+ ::COPYSHEETS_JRUBY_BUG = IS_JRUBY_PLATFORM && true
201
+ ::ERRORMESSAGE_JRUBY_BUG = IS_JRUBY_PLATFORM && true
202
+ ::CONNECT_EXCEL_JRUBY_BUG = IS_JRUBY_PLATFORM && true
203
+ ::RANGES_JRUBY_BUG = IS_JRUBY_PLATFORM && true
204
+
205
+ # @private
206
+ NetworkDrive = Struct.new(:drive_letter, :network_name) do
207
+
208
+ def self.get_all_drives
209
+ network = WIN32OLE.new('WScript.Network')
210
+ drives = network.enumnetworkdrives
211
+ ndrives = []
212
+ count = drives.Count
213
+ (0..(count - 1)).step(2) do |i|
214
+ ndrives << NetworkDrive.new( drives.Item(i), drives.Item(i + 1).tr('\\','/'))
144
215
  end
216
+ ndrives
145
217
  end
146
- raise TypeREOError, "given object cannot be type-lifted to a RobustExcelOle object"
147
218
  end
148
219
 
149
- =begin
150
- def to_reo
151
- case ole_type.name
152
- when 'Range' then RobustExcelOle::Range.new(self)
153
- when '_Worksheet' then RobustExcelOle::Worksheet.new(self)
154
- when '_Workbook' then RobustExcelOle::Workbook.new(self)
155
- when '_Application' then RobustExcelOle::Excel.new(self)
156
- else
157
- self
158
- end
159
- end
160
- =end
161
-
162
- =begin
163
- alias method_missing_before_implicit_typelift method_missing
164
-
165
- def method_missing(name, *args, &blk)
166
- puts "method_missing:"
167
- puts "name: #{name.inspect}"
168
- #raise NoMethodError if name.to_s == "Hwnd" or name.to_s == "FullName" or name.to_s == "UsedRange" or name.to_s == "Row" or name.to_s == "ListRows"
169
- begin
170
- reo_obj = self.to_reo
171
- puts "reo_obj: #{reo_obj.inspect}"
172
- rescue
173
- puts "$!.message: #{$!.message}"
174
- method_missing_before_implicit_typelift(name, *args, &blk)
175
- end
176
- reo_obj.send(name, *args, &blk)
220
+ # @private
221
+ def hostnameshare2networkpath(filename)
222
+ return filename unless filename[0,2] == "//"
223
+ NetworkDrive.get_all_drives.inject(filename) do |fn_modified, d|
224
+ fn_modified.sub(/#{(Regexp.escape(d.network_name))}/i,d.drive_letter)
225
+ end
226
+ end
227
+
228
+ # @private
229
+ def absolute_path(file)
230
+ file = file.to_path if file.respond_to?(:to_path)
231
+ return file if file[0,2] == "//"
232
+ file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
233
+ file = File.expand_path(file)
234
+ file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
235
+ WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file) #.tr('/','\\')
177
236
  end
178
- =end
179
237
 
180
- end
238
+ # @private
239
+ def canonize(filename)
240
+ raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
241
+ filename = hostnameshare2networkpath(filename)
242
+ normalize(filename) if filename
243
+ end
181
244
 
182
- # @private
183
- class ::String
184
- def / path_part
185
- if empty?
186
- path_part
187
- else
188
- if path_part.nil? || path_part.empty?
189
- self
190
- else
191
- begin
192
- File.join self, path_part
193
- rescue TypeError
194
- raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
195
- end
196
- end
197
- end
245
+ # @private
246
+ def normalize(path)
247
+ return unless path
248
+ path = path.gsub('/./', '/') + '/'
249
+ path = path.gsub(/[\/\\]+/, '/')
250
+ nil while path.gsub!(/(\/|^)(?!\.\.?)([^\/]+)\/\.\.\//, '\1')
251
+ path = path.chomp('/')
252
+ path
198
253
  end
199
254
 
200
- # taken from http://apidock.com/rails/ActiveSupport/Inflector/underscore
201
- def underscore
202
- word = gsub('::', '/')
203
- word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
204
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
205
- word.tr!('-', '_')
206
- word.downcase!
207
- word
255
+ # @private
256
+ def change_current_binding(current_object)
257
+ Pry.change_current_binding(current_object)
208
258
  end
209
259
 
210
- def delete_multiple_underscores
211
- word = self
212
- while word.index('__') do
213
- word.gsub!('__','_')
214
- end
215
- word
260
+ # @private
261
+ def class2method
262
+ [{RobustExcelOle::Excel => :Hwnd},
263
+ {RobustExcelOle::Workbook => :FullName},
264
+ {RobustExcelOle::Worksheet => :UsedRange},
265
+ {RobustExcelOle::Range => :Row},
266
+ {RobustExcelOle::ListObject => :ListRows}]
216
267
  end
217
268
 
218
- def replace_umlauts
219
- word = self
220
- word.gsub!('ä','ae')
221
- word.gsub!('Ä','Ae')
222
- word.gsub!('ö','oe')
223
- word.gsub!('Ö','Oe')
224
- word.gsub!('ü','ue')
225
- word.gsub!('Ü','Ue')
226
- #word.gsub!(/\x84/,'ae')
227
- #word.gsub!(/\x8E/,'Ae')
228
- #word.gsub!(/\x94/,'oe')
229
- #word.gsub!(/\x99/,'Oe')
230
- #word.gsub!(/\x81/,'ue')
231
- #word.gsub!(/\x9A/,'Ue')
232
- word
269
+ # @private
270
+ # enable RobustExcelOle methods to Win32Ole objects
271
+ def init_reo_for_win32ole
272
+ class2method.each do |element|
273
+ classname = element.first.first
274
+ meths = (classname.instance_methods(false) - WIN32OLE.instance_methods(false) - Object.methods - Enumerable.instance_methods(false) - [:Calculation=])
275
+ meths.each do |inst_method|
276
+ WIN32OLE.send(:define_method, inst_method) do |*args, &blk|
277
+ self.to_reo.send(inst_method, *args, &blk)
278
+ end
279
+ end
280
+ end
281
+ nil
233
282
  end
234
283
 
235
- # taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
236
- # File activesupport/lib/active_support/inflector/methods.rb, line 226
237
- def constantize # (camel_cased_word)
238
- names = split('::')
284
+ module_function :absolute_path, :canonize, :normalize, :change_current_binding, :class2method,
285
+ :init_reo_for_win32ole, :hostnameshare2networkpath, :test
239
286
 
240
- # Trigger a builtin NameError exception including the ill-formed constant in the message.
241
- Object.const_get(self) if names.empty?
287
+ end
242
288
 
243
- # Remove the first blank element in case of '::ClassName' notation.
244
- names.shift if names.size > 1 && names.first.empty?
245
289
 
246
- names.inject(Object) do |constant, name|
247
- if constant == Object
248
- constant.const_get(name)
249
- else
250
- candidate = constant.const_get(name)
251
- next candidate if constant.const_defined?(name)
252
- next candidate unless Object.const_defined?(name)
290
+ # @private
291
+ class Pry
253
292
 
254
- # Go down the ancestors to check it it's owned
255
- # directly before we reach Object or the end of ancestors.
256
- constant = constant.ancestors.inject do |const, ancestor|
257
- break const if ancestor == Object
258
- break ancestor if ancestor.const_defined?(name)
293
+ # change the current binding such that self is the current object in the pry-instance,
294
+ # preserve the local variables
259
295
 
260
- const
261
- end
296
+ class << self
297
+ attr_accessor :pry_instance
298
+ end
262
299
 
263
- # owner is in Object, so raise
264
- constant.const_get(name)
265
- end
300
+ def self.change_current_binding(current_object)
301
+ pry_instance = self.pry_instance
302
+ old_binding = pry_instance.binding_stack.pop
303
+ pry_instance.push_binding(current_object.__binding__)
304
+ exclude_vars = [:__, :_, :_dir, :_dir_, :_file, :_file_, :_in_, :_out_, :_ex, :_ex_, :pry_instance]
305
+ old_binding.local_variables.each do |var|
306
+ pry_instance.add_sticky_local(var) {old_binding.local_variable_get(var)} unless exclude_vars.include?(var)
266
307
  end
308
+ self.pry_instance = pry_instance
309
+ nil
267
310
  end
268
- end
269
311
 
270
- # taken from http://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Module.html#M000806
271
- # @private
272
- class Module
273
- def parent_name
274
- unless defined? @parent_name
275
- @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
276
- end
277
- @parent_name
312
+ def push_initial_binding(target = nil)
313
+ # memorize the current pry instance
314
+ self.class.pry_instance = self
315
+ push_binding(target || Pry.toplevel_binding)
278
316
  end
279
317
 
280
- def parent
281
- parent_name ? parent_name.constantize : Object
318
+ class REPL
319
+
320
+ def read
321
+ @indent.reset if pry.eval_string.empty?
322
+ current_prompt = pry.select_prompt
323
+ indentation = pry.config.auto_indent ? @indent.current_prefix : ''
324
+ val = read_line("#{current_prompt}#{indentation}")
325
+ # Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
326
+ return val unless val.is_a?(String)
327
+ if pry.config.auto_indent
328
+ original_val = "#{indentation}#{val}"
329
+ indented_val = @indent.indent(val)
330
+
331
+ if output.tty? &&
332
+ pry.config.correct_indent &&
333
+ Pry::Helpers::BaseHelpers.use_ansi_codes?
334
+ # avoid repeating read line
335
+
336
+ #output.print @indent.correct_indentation(
337
+ # current_prompt,
338
+ # indented_val,
339
+ # calculate_overhang(current_prompt, original_val, indented_val)
340
+ #)
341
+ output.flush
342
+ end
343
+ else
344
+ indented_val = val
345
+ end
346
+ indented_val
347
+ end
282
348
  end
283
349
  end
284
350
 
@@ -302,5 +368,3 @@ module MethodHelpers
302
368
  end
303
369
  end
304
370
  end
305
-
306
- REO = RobustExcelOle