robust_excel_ole 1.25 → 1.30

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec2281789116629bceb9d28bb49ea8c75f10306084d5d81348cd3d05f521e2ac
4
- data.tar.gz: 1adb8026858ed313c16dae70914448ce4c77a8cfc047fdf5fba15cdb41a9e448
3
+ metadata.gz: 468109a0884d48ed77c70d9681d0067453aadfbd7294c6b152fb6457141bb98d
4
+ data.tar.gz: 2527cdd343eefb7325c077204203e1893d8e32f00830a8a6591669aba7ad43ec
5
5
  SHA512:
6
- metadata.gz: f0daec2c817688fe78593042eefc2bd34c3d8e8d9eaed6cbcf1653892fc3d4e16e146832f7d9e8ddeac70d4d66bbaf22e7c72cb4e1aa27cfdf2ca2f04f29146b
7
- data.tar.gz: be997a68bd9b9c543b65c780779607210bd005db79bb448fec1c5f49cd05760213b01860555d8439ed7f91264e833e889034db7bc75e85681a77c0e224c0956a
6
+ metadata.gz: 5637d87926eef9515335fb075add5cf4810cf97229c762f2b182fbdad42cae99f128c6a2ee253acbf29362c49005d579944e283e875aff4785df5220a6f0bff6
7
+ data.tar.gz: 59f015190d12c0a0b3c7e8016e6dd81da74ae5b760e166d0044a5b04dab5d0fb0b8fa295d13f66a30861a71867c921c2352119957b0543caeb467ecd881b3223
data/Changelog CHANGED
@@ -1,6 +1,29 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.30] 2020-18-11
5
+
6
+ ## [1.29] 2020-05-11
7
+
8
+ ### Added
9
+ - Workbook.open can also take a Pathname object
10
+ - General#init_reo_for_win32ole
11
+
12
+ ## [1.28] 2020-23-10
13
+
14
+ ## [1.27] 2020-16-10
15
+
16
+ ## [1.26] 2020-09-10
17
+
18
+ ### Added
19
+ - General#change_current_binding
20
+
21
+ ## [1.25] 2020-10-09]
22
+
23
+ ## [1.24] 2020-25-09
24
+
25
+ ## [1.23] 2020-02-09
26
+
4
27
  ## [1.22] 2020-10-08
5
28
 
6
29
  ### Added
@@ -64,15 +64,7 @@ If you want to start the console under jruby, and if you don't want to use a ver
64
64
 
65
65
  jreo
66
66
 
67
- The call of the console will include RobustExcelOle for you. The consoles require the ruby gem 'pry' and 'pry-bond' to enable the ruby shell 'pry' with filename and string completion. The ruby shell 'pry' allows, among other useful things, to change the value of 'self' in the console: Let 'object' be an (almost) arbitrary object, e.g. a workbook, then you can put
68
-
69
- object.pry
70
-
71
- or
72
-
73
- cd object
74
-
75
- to assign self to this object. The original pry console is adapted to preserve local variables.
67
+ The call of the console will include RobustExcelOle for you. The consoles require the ruby gem 'pry' and 'pry-bond' to enable the ruby shell 'pry' with filename and string completion.
76
68
 
77
69
  The following examples can be used for both scripts and console. If you have started the console in the gem path, you can just put these examples.
78
70
 
@@ -326,9 +318,28 @@ and set another value to that range.
326
318
  For more details about reading and writing contents of cells and ranges see {README_ranges}[https://github.com/Thomas008/robust_excel_ole/blob/master/docs/README_ranges.rdoc]
327
319
 
328
320
 
329
- === More things
321
+ === More features
322
+
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.
328
+
329
+ object.pry
330
+
331
+ or
332
+
333
+ cd object
334
+
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. With help of +update_to_reo+ the RobustExcelOle objects and their wrapped Win32Ole objects are interchangeable. One example would be
339
+
340
+ range.ole_range.copy([4,3])
330
341
 
331
- You can convert some Win32Ole objects into a RobustExcelOle object.
342
+ Likewise it is possible to convert ("type-lift") Win32Ole objects into the corresponding RobustExcelOle object, using General.to_reo.
332
343
 
333
344
  range = sheet.Names.Item("firstcell").to_reo
334
345
 
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
 
@@ -3,8 +3,8 @@ if RUBY_PLATFORM =~ /java/
3
3
  else
4
4
  require 'win32ole'
5
5
  end
6
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/base')
7
6
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/general')
7
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/base')
8
8
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/vba_objects')
9
9
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/range_owners')
10
10
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/address_tool')
@@ -18,5 +18,4 @@ require File.join(File.dirname(__FILE__), 'robust_excel_ole/list_object')
18
18
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLATFORM =~ /cygwin/
19
19
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
20
20
 
21
- #include RobustExcelOle
22
- include General
21
+ 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
@@ -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
@@ -76,7 +77,7 @@ module RobustExcelOle
76
77
  end
77
78
  connected = (not ole_xl.nil?) && win32ole_excel.nil?
78
79
  ole_xl ||= WIN32OLE.new('Excel.Application')
79
- hwnd = ole_xl.HWnd
80
+ hwnd = ole_xl.Hwnd
80
81
  stored = hwnd2excel(hwnd)
81
82
  if stored && stored.alive?
82
83
  result = stored
@@ -297,7 +298,7 @@ module RobustExcelOle
297
298
  finishing_living_excel = alive?
298
299
  if finishing_living_excel
299
300
  hwnd = (begin
300
- @ole_excel.HWnd
301
+ @ole_excel.Hwnd
301
302
  rescue
302
303
  nil
303
304
  end)
@@ -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,74 +1,175 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require 'pathname'
2
3
 
3
- module General
4
+ # @private
5
+ module ToReoRefinement
4
6
 
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
7
+ refine WIN32OLE do
15
8
 
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('\\','/'))
9
+ # type-lifting WIN32OLE objects to RobustExcelOle objects
10
+ def to_reo
11
+ General.class2method.each do |element|
12
+ classname = element.first.first
13
+ method = element.first.last
14
+ begin
15
+ self.send(method)
16
+ if classname == RobustExcelOle::Range && self.Rows.Count == 1 && self.Columns.Count == 1
17
+ return Cell.new(self, self.Parent)
18
+ else
19
+ return classname.new(self)
20
+ end
21
+ rescue
22
+ next
23
+ end
21
24
  end
22
- ndrives
25
+ raise TypeREOError, "given object cannot be type-lifted to a RobustExcelOle object"
23
26
  end
24
27
 
25
28
  end
26
29
 
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
30
+ end
40
31
 
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
32
+ # @private
33
+ class WIN32OLE
49
34
 
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
35
+ include Enumerable
36
+
37
+ end
38
+
39
+ # @private
40
+ module FindAllIndicesRefinement
41
+
42
+ refine Array do
43
+
44
+ def find_all_indices elem
45
+ found, index, result = -1, -1, []
46
+ while found
47
+ found = self[index+1..-1].index(elem)
48
+ if found
49
+ index = index + found + 1
50
+ result << index
51
+ end
52
+ end
53
+ result
54
+ end
56
55
 
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
56
  end
66
57
 
67
- module_function :absolute_path, :canonize, :normalize
58
+ end
59
+
60
+ # @private
61
+ module StringRefinement
62
+
63
+ refine String do
64
+
65
+ def / path_part
66
+ if empty?
67
+ path_part
68
+ else
69
+ if path_part.nil? || path_part.empty?
70
+ self
71
+ else
72
+ begin
73
+ File.join self, path_part
74
+ rescue TypeError
75
+ raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ # taken from http://apidock.com/rails/ActiveSupport/Inflector/underscore
82
+ def underscore
83
+ word = gsub('::', '/')
84
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
85
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
86
+ word.tr!('-', '_')
87
+ word.downcase!
88
+ word
89
+ end
90
+
91
+ def delete_multiple_underscores
92
+ word = self
93
+ while word.index('__') do
94
+ word.gsub!('__','_')
95
+ end
96
+ word
97
+ end
98
+
99
+ def replace_umlauts
100
+ word = self
101
+ word.gsub!('ä','ae')
102
+ word.gsub!('Ä','Ae')
103
+ word.gsub!('ö','oe')
104
+ word.gsub!('Ö','Oe')
105
+ word.gsub!('ü','ue')
106
+ word.gsub!('Ü','Ue')
107
+ #word.gsub!(/\x84/,'ae')
108
+ #word.gsub!(/\x8E/,'Ae')
109
+ #word.gsub!(/\x94/,'oe')
110
+ #word.gsub!(/\x99/,'Oe')
111
+ #word.gsub!(/\x81/,'ue')
112
+ #word.gsub!(/\x9A/,'Ue')
113
+ word
114
+ end
115
+
116
+ # taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
117
+ # File activesupport/lib/active_support/inflector/methods.rb, line 226
118
+ def constantize # (camel_cased_word)
119
+ names = split('::')
120
+
121
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
122
+ Object.const_get(self) if names.empty?
123
+
124
+ # Remove the first blank element in case of '::ClassName' notation.
125
+ names.shift if names.size > 1 && names.first.empty?
68
126
 
127
+ names.inject(Object) do |constant, name|
128
+ if constant == Object
129
+ constant.const_get(name)
130
+ else
131
+ candidate = constant.const_get(name)
132
+ next candidate if constant.const_defined?(name)
133
+ next candidate unless Object.const_defined?(name)
134
+
135
+ # Go down the ancestors to check it it's owned
136
+ # directly before we reach Object or the end of ancestors.
137
+ constant = constant.ancestors.inject do |const, ancestor|
138
+ break const if ancestor == Object
139
+ break ancestor if ancestor.const_defined?(name)
140
+
141
+ const
142
+ end
143
+
144
+ # owner is in Object, so raise
145
+ constant.const_get(name)
146
+ end
147
+ end
148
+ end
149
+ end
69
150
  end
70
151
 
71
152
  # @private
153
+ module ParentRefinement
154
+
155
+ using StringRefinement
156
+
157
+ # taken from http://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Module.html#M000806
158
+ refine Module do
159
+
160
+ def parent_name
161
+ unless defined? @parent_name
162
+ @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
163
+ end
164
+ @parent_name
165
+ end
166
+
167
+ def parent
168
+ parent_name ? parent_name.constantize : Object
169
+ end
170
+ end
171
+ end
172
+
72
173
  class Integer
73
174
 
74
175
  alias old_spaceship <=>
@@ -98,179 +199,202 @@ class Array
98
199
  end
99
200
  end
100
201
 
101
- def find_each_index find
102
- found, index, q = -1, -1, []
103
- while found
104
- found = self[index+1..-1].index(find)
105
- if found
106
- index = index + found + 1
107
- q << index
108
- end
109
- end
110
- q
111
- end
112
202
  end
113
203
 
204
+
205
+ =begin
114
206
  # @private
115
- class WIN32OLE
207
+ module SpaceshipRefinement
116
208
 
117
- include Enumerable
118
-
119
- # type-lifting WIN32OLE objects to RobustExcelOle objects
120
- def to_reo
121
- class2method = [
122
- {Excel => :Hwnd},
123
- {Workbook => :FullName},
124
- {Worksheet => :UsedRange},
125
- {RobustExcelOle::Range => :Row},
126
- {ListObject => :ListRows}
127
- ]
128
- class2method.each do |element|
129
- classname = element.first.first
130
- method = element.first.last
131
- begin
132
- self.send(method)
133
- if classname == RobustExcelOle::Range && self.Rows.Count == 1 && self.Columns.Count == 1
134
- return Cell.new(self, self.Parent)
135
- else
136
- return classname.new(self)
137
- end
138
- rescue
139
- next
209
+ refine Integer do
210
+
211
+ alias old_spaceship <=>
212
+
213
+ def <=> other
214
+ # p other
215
+ if other.is_a? Array
216
+ self <=> other.first
217
+ else
218
+ old_spaceship other
140
219
  end
141
220
  end
142
- raise TypeREOError, "given object cannot be type-lifted to a RobustExcelOle object"
143
221
  end
144
222
 
223
+ refine Array do
145
224
 
146
- # def method_missing(name, *args, &blk)
147
- # puts "method_missing:"
148
- # puts "name: #{name.inspect}"
149
- # puts "self: #{self}"
150
- # puts "self.ole_type: #{self.ole_type}"
151
- # puts "self.to_reo: #{self.to_reo}"
152
- # begin
153
- # reo_obj = self.to_reo
154
- # rescue
155
- # puts "error: #{$!.message}"
156
- # raise # NoMethodError, "undefined method #{name.inspect} for #{self.inspect}"
157
- # end
158
- # reo_obj.send(name, *args, &blk)
159
- # end
160
-
161
- #alias method_missing_before_implicit_typelift method_missing
162
- #def method_missing(name, *args, &blk)
163
- # begin
164
- # reo_obj = self.to_reo
165
- # rescue
166
- # puts "$!.message: #{$!.message}"
167
- # method_missing_before_implicit_typelift(name, *args, &blk)
168
- # end
169
- # reo_obj.send(name, *args, &blk)
170
- #end
171
-
172
- end
225
+ alias old_spaceship <=>
173
226
 
174
- # @private
175
- class ::String
176
- def / path_part
177
- if empty?
178
- path_part
179
- else
180
- if path_part.nil? || path_part.empty?
181
- self
227
+ def <=> other
228
+ # p other
229
+ if other.is_a? Integer
230
+ self <=> [other]
182
231
  else
183
- begin
184
- File.join self, path_part
185
- rescue TypeError
186
- raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
187
- end
232
+ old_spaceship other
188
233
  end
189
234
  end
190
235
  end
236
+ end
237
+ =end
238
+
239
+ module General
240
+
241
+ IS_JRUBY_PLATFORM = (RUBY_PLATFORM =~ /java/)
242
+ ::EXPANDPATH_JRUBY_BUG = IS_JRUBY_PLATFORM && true
243
+ ::CONNECT_JRUBY_BUG = IS_JRUBY_PLATFORM && true
244
+ ::COPYSHEETS_JRUBY_BUG = IS_JRUBY_PLATFORM && true
245
+ ::ERRORMESSAGE_JRUBY_BUG = IS_JRUBY_PLATFORM && true
246
+ ::CONNECT_EXCEL_JRUBY_BUG = IS_JRUBY_PLATFORM && true
247
+ ::RANGES_JRUBY_BUG = IS_JRUBY_PLATFORM && true
248
+
249
+ # @private
250
+ NetworkDrive = Struct.new(:drive_letter, :network_name) do
251
+
252
+ def self.get_all(drives)
253
+ ndrives = []
254
+ count = drives.Count
255
+ (0..(count - 1)).step(2) do |i|
256
+ ndrives << NetworkDrive.new( drives.Item(i), drives.Item(i + 1).tr('\\','/'))
257
+ end
258
+ ndrives
259
+ end
191
260
 
192
- # taken from http://apidock.com/rails/ActiveSupport/Inflector/underscore
193
- def underscore
194
- word = gsub('::', '/')
195
- word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
196
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
197
- word.tr!('-', '_')
198
- word.downcase!
199
- word
200
261
  end
201
262
 
202
- def delete_multiple_underscores
203
- word = self
204
- while word.index('__') do
205
- word.gsub!('__','_')
263
+ # @private
264
+ def hostnameshare2networkpath(filename)
265
+ return filename unless filename[0,2] == "//"
266
+ network = WIN32OLE.new('WScript.Network')
267
+ drives = network.enumnetworkdrives
268
+ network_drives = NetworkDrive.get_all(drives)
269
+ f_c = filename.dup
270
+ network_drive = network_drives.find do |d|
271
+ e = f_c.sub!(d.network_name,d.drive_letter)
272
+ return e if e
206
273
  end
207
- word
208
- end
274
+ filename
275
+ end
209
276
 
210
- def replace_umlauts
211
- word = self
212
- word.gsub!('ä','ae')
213
- word.gsub!('Ä','Ae')
214
- word.gsub!('ö','oe')
215
- word.gsub!('Ö','Oe')
216
- word.gsub!('ü','ue')
217
- word.gsub!('Ü','Ue')
218
- #word.gsub!(/\x84/,'ae')
219
- #word.gsub!(/\x8E/,'Ae')
220
- #word.gsub!(/\x94/,'oe')
221
- #word.gsub!(/\x99/,'Oe')
222
- #word.gsub!(/\x81/,'ue')
223
- #word.gsub!(/\x9A/,'Ue')
224
- word
277
+ # @private
278
+ def absolute_path(file)
279
+ file = file.to_path if file.respond_to?(:to_path)
280
+ return file if file[0,2] == "//"
281
+ file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
282
+ file = File.expand_path(file)
283
+ file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
284
+ WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file) #.tr('/','\\')
225
285
  end
226
286
 
227
- # taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
228
- # File activesupport/lib/active_support/inflector/methods.rb, line 226
229
- def constantize # (camel_cased_word)
230
- names = split('::')
287
+ # @private
288
+ def canonize(filename)
289
+ raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
290
+ filename = hostnameshare2networkpath(filename)
291
+ normalize(filename) if filename
292
+ end
231
293
 
232
- # Trigger a builtin NameError exception including the ill-formed constant in the message.
233
- Object.const_get(self) if names.empty?
294
+ # @private
295
+ def normalize(path)
296
+ return unless path
297
+ path = path.gsub('/./', '/') + '/'
298
+ path = path.gsub(/[\/\\]+/, '/')
299
+ nil while path.gsub!(/(\/|^)(?!\.\.?)([^\/]+)\/\.\.\//, '\1')
300
+ path = path.chomp('/')
301
+ path
302
+ end
234
303
 
235
- # Remove the first blank element in case of '::ClassName' notation.
236
- names.shift if names.size > 1 && names.first.empty?
304
+ def change_current_binding(current_object)
305
+ Pry.change_current_binding(current_object)
306
+ end
237
307
 
238
- names.inject(Object) do |constant, name|
239
- if constant == Object
240
- constant.const_get(name)
241
- else
242
- candidate = constant.const_get(name)
243
- next candidate if constant.const_defined?(name)
244
- next candidate unless Object.const_defined?(name)
308
+ def class2method
309
+ [{RobustExcelOle::Excel => :Hwnd},
310
+ {RobustExcelOle::Workbook => :FullName},
311
+ {RobustExcelOle::Worksheet => :UsedRange},
312
+ {RobustExcelOle::Range => :Row},
313
+ {RobustExcelOle::ListObject => :ListRows}]
314
+ end
245
315
 
246
- # Go down the ancestors to check it it's owned
247
- # directly before we reach Object or the end of ancestors.
248
- constant = constant.ancestors.inject do |const, ancestor|
249
- break const if ancestor == Object
250
- break ancestor if ancestor.const_defined?(name)
316
+ using ToReoRefinement
251
317
 
252
- const
318
+ # enable RobustExcelOle methods to Win32Ole objects
319
+ def init_reo_for_win32ole
320
+ exclude_list = [:each, :each_with_index, :inspect, :Calculation=]
321
+ class2method.each do |element|
322
+ classname = element.first.first
323
+ classname.instance_methods(false).each do |inst_method|
324
+ if !exclude_list.include?(inst_method)
325
+ WIN32OLE.send(:define_method, inst_method) do |*args, &blk|
326
+ self.to_reo.send(inst_method, *args, &blk)
327
+ end
253
328
  end
254
-
255
- # owner is in Object, so raise
256
- constant.const_get(name)
257
329
  end
258
330
  end
331
+ nil
259
332
  end
333
+
334
+ module_function :absolute_path, :canonize, :normalize, :change_current_binding, :class2method,
335
+ :init_reo_for_win32ole, :hostnameshare2networkpath
336
+
260
337
  end
261
338
 
262
- # taken from http://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Module.html#M000806
339
+
263
340
  # @private
264
- class Module
265
- def parent_name
266
- unless defined? @parent_name
267
- @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
341
+ class Pry
342
+
343
+ # change the current binding such that self is the current object in the pry-instance,
344
+ # preserve the local variables
345
+
346
+ class << self
347
+ attr_accessor :pry_instance
348
+ end
349
+
350
+ def self.change_current_binding(current_object)
351
+ pry_instance = self.pry_instance
352
+ old_binding = pry_instance.binding_stack.pop
353
+ pry_instance.push_binding(current_object.__binding__)
354
+ exclude_vars = [:__, :_, :_dir, :_dir_, :_file, :_file_, :_in_, :_out_, :_ex, :_ex_, :pry_instance]
355
+ old_binding.local_variables.each do |var|
356
+ pry_instance.add_sticky_local(var) {old_binding.local_variable_get(var)} unless exclude_vars.include?(var)
268
357
  end
269
- @parent_name
358
+ self.pry_instance = pry_instance
359
+ nil
270
360
  end
271
361
 
272
- def parent
273
- parent_name ? parent_name.constantize : Object
362
+ def push_initial_binding(target = nil)
363
+ # memorize the current pry instance
364
+ self.class.pry_instance = self
365
+ push_binding(target || Pry.toplevel_binding)
366
+ end
367
+
368
+ class REPL
369
+
370
+ def read
371
+ @indent.reset if pry.eval_string.empty?
372
+ current_prompt = pry.select_prompt
373
+ indentation = pry.config.auto_indent ? @indent.current_prefix : ''
374
+ val = read_line("#{current_prompt}#{indentation}")
375
+ # Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
376
+ return val unless val.is_a?(String)
377
+ if pry.config.auto_indent
378
+ original_val = "#{indentation}#{val}"
379
+ indented_val = @indent.indent(val)
380
+
381
+ if output.tty? &&
382
+ pry.config.correct_indent &&
383
+ Pry::Helpers::BaseHelpers.use_ansi_codes?
384
+ # avoid repeating read line
385
+
386
+ #output.print @indent.correct_indentation(
387
+ # current_prompt,
388
+ # indented_val,
389
+ # calculate_overhang(current_prompt, original_val, indented_val)
390
+ #)
391
+ output.flush
392
+ end
393
+ else
394
+ indented_val = val
395
+ end
396
+ indented_val
397
+ end
274
398
  end
275
399
  end
276
400
 
@@ -293,7 +417,4 @@ module MethodHelpers
293
417
  super
294
418
  end
295
419
  end
296
-
297
420
  end
298
-
299
- REO = RobustExcelOle